feat: update profile path resolution and enhance scripts for improved project adaptability

This commit is contained in:
2026-05-21 10:43:44 -06:00
parent f0d3cd4ce9
commit 7cbb49134a
18 changed files with 98 additions and 32 deletions

View File

@@ -41,7 +41,7 @@ bash scripts/memory/memory.sh search "PDIAP-15765"
bash scripts/memory/memory.sh create work-item pdiap-15999 "Example title" bash scripts/memory/memory.sh create work-item pdiap-15999 "Example title"
``` ```
This interface defaults to Markdown files under `project-knowledge/`, uses Obsidian CLI when useful and available, and falls back to direct file operations. This interface resolves the canonical Markdown directory from `profiles/<profile>/workspace.json`, uses Obsidian CLI when useful and available, and falls back to direct file operations.
The default workspace Mattermost extractor now lives in: The default workspace Mattermost extractor now lives in:
@@ -79,7 +79,7 @@ Expected behavior:
- avoid interactive prompts - avoid interactive prompts
- return a non-zero exit code on failure - return a non-zero exit code on failure
OpenCode can then use that output to refresh `ai/inbox/mattermost-latest.md` proactively. When the local Mattermost proxy mirror is running, commands should prefer `ai/inbox/mattermost-mirror/` through `scripts/mattermost-proxy/read-context.py` and use legacy sync output as fallback evidence. OpenCode can then use that output to refresh the active profile inbox proactively. When the local Mattermost proxy mirror is running, commands should prefer `<profile inbox>/mattermost-mirror/` through `scripts/mattermost-proxy/read-context.py --profile <profile>` and use legacy sync output only as fallback evidence.
Historical Slack exports can also be imported through: Historical Slack exports can also be imported through:

View File

@@ -34,7 +34,7 @@ The service manager unifies startup and status. It does not move capture behavio
## Local project-knowledge index ## Local project-knowledge index
The workspace includes a dependency-free local indexer for canonical Markdown memory. The index is derived from `project-knowledge/` and written under `.aiw/indexes/<profile>/`; it is safe to delete and rebuild. The workspace includes a dependency-free local indexer for canonical Markdown memory. The index is derived from the profile's configured `knowledge_dir` and written under the profile's configured `index_dir`; it is safe to delete and rebuild.
```bash ```bash
python3 scripts/aiw/indexer.py build --profile fidelity python3 scripts/aiw/indexer.py build --profile fidelity
@@ -62,7 +62,7 @@ Current fields:
} }
``` ```
Use `scripts/aiw/profile.py` from new scripts instead of hardcoding root-level `project-knowledge/` or `ai/inbox/` paths. Use `scripts/aiw/profile.py` from new scripts instead of hardcoding root-level project memory or inbox paths.
## Robustness features ## Robustness features

View File

@@ -8,6 +8,7 @@ instead of hardcoding root-level project paths.
from __future__ import annotations from __future__ import annotations
import json import json
import argparse
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
@@ -70,3 +71,37 @@ def relative_to_root(path: Path, root: Path | None = None) -> str:
return str(path.relative_to(base)) return str(path.relative_to(base))
except ValueError: except ValueError:
return str(path) return str(path)
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
subparsers = parser.add_subparsers(dest="command", required=True)
path_parser = subparsers.add_parser("path", help="Print a resolved profile path.")
path_parser.add_argument("kind", choices=["knowledge", "inbox", "index"])
path_parser.add_argument("--profile", default="fidelity")
config_parser = subparsers.add_parser("config", help="Print resolved workspace configuration as JSON.")
config_parser.add_argument("--profile", default="fidelity")
args = parser.parse_args()
if args.command == "path":
if args.kind == "knowledge":
print(knowledge_dir(args.profile))
elif args.kind == "inbox":
print(inbox_dir(args.profile))
else:
print(index_dir(args.profile))
return
config = load_workspace_config(args.profile)
config["resolved"] = {
"knowledge_dir": str(knowledge_dir(args.profile)),
"inbox_dir": str(inbox_dir(args.profile)),
"index_dir": str(index_dir(args.profile)),
}
print(json.dumps(config, ensure_ascii=False, indent=2, sort_keys=True))
if __name__ == "__main__":
main()

View File

@@ -42,6 +42,12 @@ class ProfileTests(unittest.TestCase):
self.assertEqual(profile.inbox_dir("missing", root=root), root / "ai" / "inbox") self.assertEqual(profile.inbox_dir("missing", root=root), root / "ai" / "inbox")
self.assertEqual(profile.index_dir("missing", root=root), root / ".aiw" / "indexes" / "missing") self.assertEqual(profile.index_dir("missing", root=root), root / ".aiw" / "indexes" / "missing")
def test_relative_to_root_handles_external_paths(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
self.assertEqual(profile.relative_to_root(root / "a" / "b", root=root), "a/b")
self.assertEqual(profile.relative_to_root(Path("/external/path"), root=root), "/external/path")
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View File

@@ -152,17 +152,18 @@ Keep this utility as an isolated image mailbox. If a project wants easy access,
link the project inbox to the mailbox instead of making this utility know about link the project inbox to the mailbox instead of making this utility know about
the project. the project.
Example: Example using the active profile inbox:
```bash ```bash
mkdir -p ai/inbox PROFILE_INBOX="$(python3 scripts/aiw/profile.py path inbox --profile fidelity)"
ln -s "$HOME/Pictures/Photo Inbox" ai/inbox/photos mkdir -p "$PROFILE_INBOX"
ln -s "$HOME/Pictures/Photo Inbox" "$PROFILE_INBOX/photos"
``` ```
Or point the receiver at a project-owned folder from `.env`: Or point the receiver at a project-owned folder from `.env`:
```bash ```bash
PHOTO_INBOX_DIR=/absolute/path/to/project/ai/inbox/photos PHOTO_INBOX_DIR=/absolute/path/to/profile/inbox/photos
``` ```
The symlink approach keeps this utility reusable across projects and devices. The symlink approach keeps this utility reusable across projects and devices.

View File

@@ -7,7 +7,9 @@
MATTERMOST_MIRROR_HOST_ALLOW= MATTERMOST_MIRROR_HOST_ALLOW=
# Output directory for raw evidence and normalized AI-readable context. # Output directory for raw evidence and normalized AI-readable context.
MATTERMOST_MIRROR_DIR=ai/inbox/mattermost-mirror # Optional. If omitted, run-mirror.sh writes to the active profile inbox:
# <inbox_dir from profiles/<profile>/workspace.json>/mattermost-mirror
# MATTERMOST_MIRROR_DIR=/absolute/path/to/mattermost-mirror
# mitmproxy listener used by launch-mattermost.sh. # mitmproxy listener used by launch-mattermost.sh.
MATTERMOST_MIRROR_LISTEN_HOST=127.0.0.1 MATTERMOST_MIRROR_LISTEN_HOST=127.0.0.1

View File

@@ -2,7 +2,7 @@
Local read-only Mattermost Desktop mirror for AI workspace context. Local read-only Mattermost Desktop mirror for AI workspace context.
This is for **raw evidence only**. It writes under `ai/inbox/mattermost-mirror/`; durable project memory still belongs in `project-knowledge/` after normal promotion rules. This is for **raw evidence only**. By default it writes under the active profile inbox at `<inbox_dir>/mattermost-mirror/`; durable project memory still belongs in the profile's canonical project knowledge vault after normal promotion rules.
## Why this exists ## Why this exists
@@ -48,7 +48,7 @@ missing.
## Output layout ## Output layout
```text ```text
ai/inbox/mattermost-mirror/ <profile inbox>/mattermost-mirror/
latest.jsonl # bounded AI-readable window latest.jsonl # bounded AI-readable window
latest.md # bounded Markdown view latest.md # bounded Markdown view
state.json # last seen by channel and user cache state.json # last seen by channel and user cache
@@ -138,7 +138,7 @@ Each line in the normalized JSONL contains:
## Useful environment variables ## Useful environment variables
- `MATTERMOST_MIRROR_HOST_ALLOW`: exact host or parent domain to capture. - `MATTERMOST_MIRROR_HOST_ALLOW`: exact host or parent domain to capture.
- `MATTERMOST_MIRROR_DIR`: output directory, default `ai/inbox/mattermost-mirror`. - `MATTERMOST_MIRROR_DIR`: optional output directory. If omitted, `run-mirror.sh` uses `<inbox_dir from profiles/<profile>/workspace.json>/mattermost-mirror`.
- `MATTERMOST_MIRROR_LATEST_LIMIT`: number of messages in `latest.*`, default `200`. - `MATTERMOST_MIRROR_LATEST_LIMIT`: number of messages in `latest.*`, default `200`.
- `MATTERMOST_MIRROR_CHANNEL_IDS`: optional comma-separated channel ID allowlist. - `MATTERMOST_MIRROR_CHANNEL_IDS`: optional comma-separated channel ID allowlist.
- `MATTERMOST_MIRROR_WRITE_RAW`: set to `1` to save compact raw REST/WebSocket evidence. - `MATTERMOST_MIRROR_WRITE_RAW`: set to `1` to save compact raw REST/WebSocket evidence.
@@ -170,7 +170,7 @@ do not create message files. Open a channel, open a thread, scroll slightly in
history, or wait for/send a new message. Then check: history, or wait for/send a new message. Then check:
```text ```text
ai/inbox/mattermost-mirror/latest.md <profile inbox>/mattermost-mirror/latest.md
ai/inbox/mattermost-mirror/channels/<channel-name>/YYYY/MM/YYYY-MM-DD.jsonl <profile inbox>/mattermost-mirror/channels/<channel-name>/YYYY/MM/YYYY-MM-DD.jsonl
ai/inbox/mattermost-mirror/by-date/YYYY/MM/YYYY-MM-DD.jsonl <profile inbox>/mattermost-mirror/by-date/YYYY/MM/YYYY-MM-DD.jsonl
``` ```

View File

@@ -6,7 +6,7 @@ This addon is intentionally narrow:
- redact secrets - redact secrets
- normalize posts into date-rotated JSONL files for AI context - normalize posts into date-rotated JSONL files for AI context
The output under ai/inbox/ is raw evidence, not canonical project memory. The output under the profile inbox is raw evidence, not canonical project memory.
""" """
from __future__ import annotations from __future__ import annotations
@@ -23,7 +23,7 @@ from urllib.parse import urlparse
from mitmproxy import http from mitmproxy import http
DEFAULT_OUT_DIR = "ai/inbox/mattermost-mirror" DEFAULT_OUT_DIR = "mattermost-mirror"
POST_ID_RE = re.compile(r"^[a-z0-9]{26}$") POST_ID_RE = re.compile(r"^[a-z0-9]{26}$")
SAFE_NAME_RE = re.compile(r"[^a-zA-Z0-9._-]+") SAFE_NAME_RE = re.compile(r"[^a-zA-Z0-9._-]+")

View File

@@ -13,17 +13,29 @@ import argparse
import json import json
import os import os
import shlex import shlex
import sys
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from pathlib import Path from pathlib import Path
ROOT = Path(__file__).resolve().parents[2] ROOT = Path(__file__).resolve().parents[2]
MIRROR_DIR = ROOT / "ai" / "inbox" / "mattermost-mirror" sys.path.insert(0, str(ROOT / "scripts" / "aiw"))
LEGACY_LATEST = ROOT / "ai" / "inbox" / "mattermost-latest.md" import profile as aiw_profile # noqa: E402
DEFAULT_PROFILE = os.getenv("AIW_PROJECT_PROFILE", "fidelity")
MIRROR_DIR = aiw_profile.inbox_dir(DEFAULT_PROFILE, root=ROOT) / "mattermost-mirror"
LEGACY_LATEST = aiw_profile.inbox_dir(DEFAULT_PROFILE, root=ROOT) / "mattermost-latest.md"
LEGACY_GENERATED = ROOT / "scripts" / "mattermost" / "generated" / "mattermost_context.jsonl" LEGACY_GENERATED = ROOT / "scripts" / "mattermost" / "generated" / "mattermost_context.jsonl"
LOCAL_ENV = Path(__file__).resolve().parent / ".env" LOCAL_ENV = Path(__file__).resolve().parent / ".env"
def configure_profile_paths(profile: str) -> None:
global MIRROR_DIR, LEGACY_LATEST
inbox = aiw_profile.inbox_dir(profile, root=ROOT)
MIRROR_DIR = inbox / "mattermost-mirror"
LEGACY_LATEST = inbox / "mattermost-latest.md"
def load_local_env(path: Path = LOCAL_ENV) -> None: def load_local_env(path: Path = LOCAL_ENV) -> None:
"""Load simple KEY=VALUE pairs from the connector-local .env. """Load simple KEY=VALUE pairs from the connector-local .env.
@@ -201,6 +213,7 @@ def main() -> None:
load_local_env() load_local_env()
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--profile", default=DEFAULT_PROFILE)
parser.add_argument("--mode", choices=["latest", "previous-workday", "standup", "focused"], default="latest") parser.add_argument("--mode", choices=["latest", "previous-workday", "standup", "focused"], default="latest")
parser.add_argument("--today", default="") parser.add_argument("--today", default="")
parser.add_argument( parser.add_argument(
@@ -210,6 +223,7 @@ def main() -> None:
) )
parser.add_argument("--limit", type=int, default=80, help="Max records per section; use 0 for no limit.") parser.add_argument("--limit", type=int, default=80, help="Max records per section; use 0 for no limit.")
args = parser.parse_args() args = parser.parse_args()
configure_profile_paths(args.profile)
channels = parse_channels(args.channels or None) channels = parse_channels(args.channels or None)
limit = args.limit if args.limit > 0 else None limit = args.limit if args.limit > 0 else None

View File

@@ -11,7 +11,9 @@ if [ -f "$SCRIPT_DIR/.env" ]; then
set +a set +a
fi fi
export MATTERMOST_MIRROR_DIR="${MATTERMOST_MIRROR_DIR:-$WORKSPACE_ROOT/ai/inbox/mattermost-mirror}" PROFILE="${AIW_PROJECT_PROFILE:-fidelity}"
PROFILE_INBOX_DIR="$(python3 "$WORKSPACE_ROOT/scripts/aiw/profile.py" path inbox --profile "$PROFILE")"
export MATTERMOST_MIRROR_DIR="${MATTERMOST_MIRROR_DIR:-$PROFILE_INBOX_DIR/mattermost-mirror}"
export MATTERMOST_MIRROR_LISTEN_HOST="${MATTERMOST_MIRROR_LISTEN_HOST:-127.0.0.1}" export MATTERMOST_MIRROR_LISTEN_HOST="${MATTERMOST_MIRROR_LISTEN_HOST:-127.0.0.1}"
export MATTERMOST_MIRROR_LISTEN_PORT="${MATTERMOST_MIRROR_LISTEN_PORT:-8080}" export MATTERMOST_MIRROR_LISTEN_PORT="${MATTERMOST_MIRROR_LISTEN_PORT:-8080}"

View File

@@ -3,7 +3,7 @@
This directory contains the workspace-local Mattermost extractor used by OpenCode to refresh communication context. This directory contains the workspace-local Mattermost extractor used by OpenCode to refresh communication context.
The preferred live Mattermost evidence source is now the proxy mirror under The preferred live Mattermost evidence source is now the proxy mirror under
`ai/inbox/mattermost-mirror/` when it is running. This legacy extractor remains the active profile inbox, `<profile inbox>/mattermost-mirror/`, when it is running. This legacy extractor remains
the fallback and explicit refresh path for commands that need a fresh pull from the fallback and explicit refresh path for commands that need a fresh pull from
the Mattermost API. the Mattermost API.
@@ -72,7 +72,7 @@ Generic workspace variables are preferred for reusable projects:
- `AIW_MATTERMOST_SYNC_CMD` - `AIW_MATTERMOST_SYNC_CMD`
- `AIW_MATTERMOST_SYNC_INTERVAL_MINUTES` - `AIW_MATTERMOST_SYNC_INTERVAL_MINUTES`
The older `FIDELITY_*` variables remain supported for this project profile. Profile-specific compatibility variables may exist for older project setups, but new reusable workflows should prefer the generic `AIW_*` variables.
Previous workday mode for standups: Previous workday mode for standups:

View File

@@ -45,7 +45,7 @@ python3 scripts/mcp/aiw-context-mcp/server.py --transport stdio
- `memory_hybrid_search` - `memory_hybrid_search`
- `photos_latest` - `photos_latest`
All tools are read-only. Mattermost tools read `ai/inbox/mattermost-mirror/`; photo tools list local Photo Inbox files without embedding image data; project tools read canonical Markdown under `project-knowledge/`. All tools are read-only. Mattermost tools read the active profile's `mattermost-mirror/` inbox; photo tools list local Photo Inbox files without embedding image data; project tools read canonical Markdown from the profile's configured `knowledge_dir`.
`memory_hybrid_search` reads the derived local index built by: `memory_hybrid_search` reads the derived local index built by:
@@ -53,7 +53,7 @@ All tools are read-only. Mattermost tools read `ai/inbox/mattermost-mirror/`; ph
python3 scripts/aiw/indexer.py build --profile fidelity python3 scripts/aiw/indexer.py build --profile fidelity
``` ```
If the index is missing, it falls back to bounded live Markdown search over `project-knowledge/`. The index is not canonical memory; `project-knowledge/` remains the source of truth. If the index is missing, it falls back to bounded live Markdown search over the profile's configured knowledge directory. The index is not canonical memory; Markdown remains the source of truth.
Mattermost latest/date/standup tools filter to the active profile's context channels by default. For Fidelity, that list lives in `profiles/fidelity/context-sources.json`. Pass explicit `channels` to override the profile list, or `include_all_channels: true` when broad unfiltered mirror evidence is intentionally needed. Mattermost latest/date/standup tools filter to the active profile's context channels by default. For Fidelity, that list lives in `profiles/fidelity/context-sources.json`. Pass explicit `channels` to override the profile list, or `include_all_channels: true` when broad unfiltered mirror evidence is intentionally needed.

View File

@@ -2,12 +2,13 @@
This directory exposes a project-agnostic interface for canonical project knowledge. This directory exposes a project-agnostic interface for canonical project knowledge.
The current implementation uses Markdown files under `project-knowledge/` and can optionally delegate to the Obsidian CLI when it is available. The agent should depend on this memory interface, not on Obsidian-specific behavior, so the backing tool can be replaced later. The current implementation resolves the canonical Markdown directory from `profiles/<profile>/workspace.json` and can optionally delegate to the Obsidian CLI when it is available. The agent should depend on this memory interface, not on Obsidian-specific behavior, so the backing tool can be replaced later.
## Backend Model ## Backend Model
- `AIW_PROJECT_KNOWLEDGE_DIR` points to the canonical Markdown project knowledge directory. - `AIW_PROJECT_PROFILE` selects the profile, defaulting to `fidelity` in this repository.
- `AIW_MEMORY_VAULT_DIR` and `AIW_OBSIDIAN_VAULT_DIR` are transition aliases. - `profiles/<profile>/workspace.json` defines the canonical Markdown project knowledge directory.
- `AIW_PROJECT_KNOWLEDGE_DIR` can override the resolved directory for local experiments.
- `AIW_MEMORY_BACKEND` defaults to `auto`. - `AIW_MEMORY_BACKEND` defaults to `auto`.
- `auto` uses Obsidian CLI when it is useful and available, then falls back to direct Markdown operations. - `auto` uses Obsidian CLI when it is useful and available, then falls back to direct Markdown operations.
- `files` forces direct Markdown operations. - `files` forces direct Markdown operations.

View File

@@ -4,7 +4,8 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
PROJECT_KNOWLEDGE_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-${AIW_MEMORY_VAULT_DIR:-${AIW_OBSIDIAN_VAULT_DIR:-$WORKSPACE_ROOT/project-knowledge}}}" PROFILE="${AIW_PROJECT_PROFILE:-fidelity}"
PROJECT_KNOWLEDGE_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-$(python3 "$WORKSPACE_ROOT/scripts/aiw/profile.py" path knowledge --profile "$PROFILE")}"
VAULT_DIR="$PROJECT_KNOWLEDGE_DIR" VAULT_DIR="$PROJECT_KNOWLEDGE_DIR"
BACKEND="${AIW_MEMORY_BACKEND:-auto}" BACKEND="${AIW_MEMORY_BACKEND:-auto}"
OBSIDIAN_CLI="$WORKSPACE_ROOT/scripts/obsidian/cli.sh" OBSIDIAN_CLI="$WORKSPACE_ROOT/scripts/obsidian/cli.sh"

View File

@@ -4,7 +4,8 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
VAULT_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-${AIW_MEMORY_VAULT_DIR:-${AIW_OBSIDIAN_VAULT_DIR:-$WORKSPACE_ROOT/project-knowledge}}}" PROFILE="${AIW_PROJECT_PROFILE:-fidelity}"
VAULT_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-$(python3 "$WORKSPACE_ROOT/scripts/aiw/profile.py" path knowledge --profile "$PROFILE")}"
if ! command -v obsidian >/dev/null 2>&1; then if ! command -v obsidian >/dev/null 2>&1; then
echo "obsidian CLI is not installed or not in PATH" >&2 echo "obsidian CLI is not installed or not in PATH" >&2

View File

@@ -4,7 +4,8 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
VAULT_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-${AIW_MEMORY_VAULT_DIR:-${AIW_OBSIDIAN_VAULT_DIR:-$WORKSPACE_ROOT/project-knowledge}}}" PROFILE="${AIW_PROJECT_PROFILE:-fidelity}"
VAULT_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-$(python3 "$WORKSPACE_ROOT/scripts/aiw/profile.py" path knowledge --profile "$PROFILE")}"
VAULT_NAME="${AIW_OBSIDIAN_VAULT_NAME:-$(basename "$VAULT_DIR")}" VAULT_NAME="${AIW_OBSIDIAN_VAULT_NAME:-$(basename "$VAULT_DIR")}"
URI="$("$SCRIPT_DIR/uri.sh" daily "vault=$VAULT_NAME")" URI="$("$SCRIPT_DIR/uri.sh" daily "vault=$VAULT_NAME")"

View File

@@ -4,7 +4,8 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
VAULT_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-${AIW_MEMORY_VAULT_DIR:-${AIW_OBSIDIAN_VAULT_DIR:-$WORKSPACE_ROOT/project-knowledge}}}" PROFILE="${AIW_PROJECT_PROFILE:-fidelity}"
VAULT_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-$(python3 "$WORKSPACE_ROOT/scripts/aiw/profile.py" path knowledge --profile "$PROFILE")}"
VAULT_NAME="${AIW_OBSIDIAN_VAULT_NAME:-$(basename "$VAULT_DIR")}" VAULT_NAME="${AIW_OBSIDIAN_VAULT_NAME:-$(basename "$VAULT_DIR")}"
if [[ $# -lt 1 ]]; then if [[ $# -lt 1 ]]; then

View File

@@ -4,7 +4,8 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
VAULT_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-${AIW_MEMORY_VAULT_DIR:-${AIW_OBSIDIAN_VAULT_DIR:-$WORKSPACE_ROOT/project-knowledge}}}" PROFILE="${AIW_PROJECT_PROFILE:-fidelity}"
VAULT_DIR="${AIW_PROJECT_KNOWLEDGE_DIR:-$(python3 "$WORKSPACE_ROOT/scripts/aiw/profile.py" path knowledge --profile "$PROFILE")}"
VAULT_NAME="${AIW_OBSIDIAN_VAULT_NAME:-$(basename "$VAULT_DIR")}" VAULT_NAME="${AIW_OBSIDIAN_VAULT_NAME:-$(basename "$VAULT_DIR")}"
if [[ $# -lt 1 ]]; then if [[ $# -lt 1 ]]; then