stealthos-cli 0.1.0-alpha.3 → 0.1.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ai/CONTRACT.md +110 -0
- package/ai/INDEX.md +203 -0
- package/ai/README.md +434 -0
- package/ai/ROUTER.md +288 -0
- package/ai/agents/README.md +103 -0
- package/ai/agents/architect.md +59 -0
- package/ai/agents/backend-engineer.md +62 -0
- package/ai/agents/founder.md +45 -0
- package/ai/agents/frontend-engineer.md +61 -0
- package/ai/agents/product-manager.md +56 -0
- package/ai/agents/qa-engineer.md +53 -0
- package/ai/agents/researcher.md +74 -0
- package/ai/agents/reviewer.md +73 -0
- package/ai/agents/security-engineer.md +59 -0
- package/ai/agents/sre-engineer.md +70 -0
- package/ai/agents/tech-lead.md +70 -0
- package/ai/architecture/README.md +35 -0
- package/ai/architecture/components.md +24 -0
- package/ai/architecture/containers.md +30 -0
- package/ai/architecture/event-flows.md +36 -0
- package/ai/architecture/sequence-diagrams.md +38 -0
- package/ai/architecture/system-context.md +46 -0
- package/ai/architecture/threat-modeling.md +40 -0
- package/ai/blueprints/README.md +67 -0
- package/ai/blueprints/_schema.json +40 -0
- package/ai/blueprints/ai-platform.json +28 -0
- package/ai/blueprints/crm.json +22 -0
- package/ai/blueprints/game.json +25 -0
- package/ai/blueprints/mobile.json +24 -0
- package/ai/blueprints/realtime.json +22 -0
- package/ai/blueprints/saas.json +25 -0
- package/ai/blueprints/telemetry.json +30 -0
- package/ai/blueprints/web.json +23 -0
- package/ai/bootstrap/discovery-questions.md +117 -0
- package/ai/bootstrap/dispatcher.md +85 -0
- package/ai/bootstrap/existing-project.md +191 -0
- package/ai/bootstrap/new-project.md +127 -0
- package/ai/bootstrap/tech-mapping.md +164 -0
- package/ai/clients/README.md +114 -0
- package/ai/clients/antigravity.md +125 -0
- package/ai/clients/claude-code.md +65 -0
- package/ai/clients/cline.md +69 -0
- package/ai/clients/codex-aider-cli.md +82 -0
- package/ai/clients/continue.md +67 -0
- package/ai/clients/copilot.md +49 -0
- package/ai/clients/cursor.md +81 -0
- package/ai/clients/snippets/mcp-absolute-paths.json +9 -0
- package/ai/clients/snippets/mcp-http.json +7 -0
- package/ai/clients/snippets/mcp-stdio.json +9 -0
- package/ai/clients/trae.md +69 -0
- package/ai/clients/windsurf.md +71 -0
- package/ai/core/pipeline/execution-engine.md +157 -0
- package/ai/engineering/README.md +32 -0
- package/ai/engineering/observability/incident-response.md +82 -0
- package/ai/evals/protocol-tests.md +150 -0
- package/ai/evolution/agent-evolution.md +161 -0
- package/ai/evolution/improvements.md +91 -0
- package/ai/evolution/learnings.md +49 -0
- package/ai/evolution/patterns-discovered.md +48 -0
- package/ai/execution/README.md +33 -0
- package/ai/execution/backlog.md +27 -0
- package/ai/execution/milestones.md +26 -0
- package/ai/execution/roadmap.md +30 -0
- package/ai/execution/sprint.md +42 -0
- package/ai/governance/README.md +34 -0
- package/ai/governance/architecture-principles.md +99 -0
- package/ai/governance/definition-of-done.md +88 -0
- package/ai/governance/definition-of-ready.md +69 -0
- package/ai/governance/engineering-principles.md +70 -0
- package/ai/governance/quality-gates.md +85 -0
- package/ai/governance/security-policies.md +84 -0
- package/ai/hooks/enforce-audit.ps1 +41 -0
- package/ai/hooks/enforce-audit.sh +39 -0
- package/ai/hooks/guard-edit.ps1 +182 -0
- package/ai/hooks/guard-edit.sh +161 -0
- package/ai/hooks/inject-os-reminder.ps1 +40 -0
- package/ai/hooks/inject-os-reminder.sh +16 -0
- package/ai/manifest.json +238 -0
- package/ai/memory/_detected-stack.json +33 -0
- package/ai/memory/_summary.md +49 -0
- package/ai/memory/archive/.gitkeep +3 -0
- package/ai/memory/completed-tasks.md +156 -0
- package/ai/memory/decisions.md +257 -0
- package/ai/memory/errors-and-solutions.md +41 -0
- package/ai/memory/known-issues.md +40 -0
- package/ai/memory/pending-tasks.md +37 -0
- package/ai/memory/project-context.md +67 -0
- package/ai/operating-system/architecture.md +54 -0
- package/ai/operating-system/coding-standards.md +84 -0
- package/ai/operating-system/folder-structure.md +126 -0
- package/ai/operating-system/performance-rules.md +86 -0
- package/ai/operating-system/quality-control.md +81 -0
- package/ai/operating-system/security-rules.md +91 -0
- package/ai/operating-system/workflow.md +86 -0
- package/ai/product/README.md +24 -0
- package/ai/product/business-rules.md +26 -0
- package/ai/product/personas.md +29 -0
- package/ai/product/user-journeys.md +30 -0
- package/ai/product/vision.md +35 -0
- package/ai/rules/behavior.md +45 -0
- package/ai/rules/do.md +47 -0
- package/ai/rules/dont.md +46 -0
- package/ai/rules/execution-flow.md +125 -0
- package/ai/rules/structural-constraints.md +59 -0
- package/ai/rules/structure-canon.md +116 -0
- package/ai/runtime.md +179 -0
- package/ai/scripts/detect-stack.ps1 +166 -0
- package/ai/scripts/detect-stack.sh +172 -0
- package/ai/scripts/init-ai-os.ps1 +170 -0
- package/ai/scripts/init-ai-os.sh +99 -0
- package/ai/scripts/lint-os.ps1 +99 -0
- package/ai/scripts/lint-os.sh +85 -0
- package/ai/scripts/start-os.ps1 +151 -0
- package/ai/scripts/start-os.sh +141 -0
- package/ai/server/README.md +105 -0
- package/ai/server/aios-server.mjs +2134 -0
- package/ai/server/package-lock.json +802 -0
- package/ai/server/package.json +31 -0
- package/ai/server/src/analyzer/graph-builder.ts +92 -0
- package/ai/server/src/analyzer/index.ts +191 -0
- package/ai/server/src/analyzer/module-mapper.ts +171 -0
- package/ai/server/src/analyzer/smell-detector.ts +54 -0
- package/ai/server/src/analyzer/stack-detector.ts +70 -0
- package/ai/server/src/index.ts +16 -0
- package/ai/server/src/packager/context-builder.ts +217 -0
- package/ai/server/src/packager/index.ts +3 -0
- package/ai/server/src/packager/memory-injector.ts +128 -0
- package/ai/server/src/packager/module-summarizer.ts +60 -0
- package/ai/server/src/packager/token-estimator.ts +26 -0
- package/ai/server/src/snapshot/index.ts +3 -0
- package/ai/server/src/snapshot/snapshot-creator.ts +206 -0
- package/ai/server/src/snapshot/snapshot-diff.ts +86 -0
- package/ai/server/src/snapshot/snapshot-restore.ts +14 -0
- package/ai/server/src/types.ts +94 -0
- package/ai/server/tsconfig.json +26 -0
- package/ai/skills/architecture-design.md +82 -0
- package/ai/skills/backend-engineering.md +57 -0
- package/ai/skills/database-design.md +76 -0
- package/ai/skills/frontend-engineering.md +63 -0
- package/ai/skills/performance.md +73 -0
- package/ai/skills/scalability.md +84 -0
- package/ai/skills/security.md +71 -0
- package/ai/skills/testing.md +77 -0
- package/ai/specs/ADR/ADR-0002-typescript-runtime.md +103 -0
- package/ai/specs/ADR/ADR-0004-runtime-orchestrator.md +94 -0
- package/ai/specs/ADR/ADR-0005-workflow-engine.md +105 -0
- package/ai/specs/ADR/ADR-0006-runtime-state.md +104 -0
- package/ai/specs/ADR/ADR-0007-state-compiler-drift-context-layers-artifact-index.md +82 -0
- package/ai/specs/ADR/ADR-0008-intent-runtime-discovery-branching.md +93 -0
- package/ai/specs/ADR/ADR-0009-confidence-system-maturity-tracking.md +113 -0
- package/ai/specs/ADR/ADR-0010-structural-architecture-standards.md +121 -0
- package/ai/specs/ADR/ADR-0011-mcp-prompts.md +86 -0
- package/ai/specs/ADR/ADR-0012-stealthos-hybrid-architecture.md +174 -0
- package/ai/specs/ADR/_TEMPLATE.md +60 -0
- package/ai/specs/BRD/_TEMPLATE.md +50 -0
- package/ai/specs/PRD/_TEMPLATE.md +72 -0
- package/ai/specs/README.md +43 -0
- package/ai/specs/RFC/RFC-0001-runtime-orchestrator.md +149 -0
- package/ai/specs/RFC/RFC-0002-runtime-orchestrator-extended.md +134 -0
- package/ai/specs/RFC/_TEMPLATE.md +61 -0
- package/ai/specs/RUNBOOKS/_TEMPLATE.md +68 -0
- package/ai/specs/SDD/_TEMPLATE.md +104 -0
- package/ai/specs/TASKS/_TEMPLATE.md +52 -0
- package/ai/tools/debugging.md +64 -0
- package/ai/tools/dependency-analysis.md +46 -0
- package/ai/tools/internet-research.md +42 -0
- package/ai/tools/mcp-discovery.md +44 -0
- package/ai/workflows/_schema.json +81 -0
- package/ai/workflows/init.json +148 -0
- package/ai/workflows/sync.json +71 -0
- package/ai/workflows/work.json +91 -0
- package/package.json +7 -1
- package/scripts/bundle-ai.mjs +58 -0
- package/src/cli.mjs +1 -1
- package/src/commands/install.mjs +35 -11
- package/src/lib/resolve-source.mjs +27 -10
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./_schema.json",
|
|
3
|
+
"id": "work",
|
|
4
|
+
"version": "3.0.0",
|
|
5
|
+
"description": "Intent Runtime completo: carrega runtime-context compilado, classifica, faz gap analysis, pode pausar para clarification se complex, gera plan, pausa para approval, executa (LLM externa faz tool calls), valida, atualiza memory, snapshot final.",
|
|
6
|
+
"safety": { "project_files_readonly": false },
|
|
7
|
+
"guarantees": [
|
|
8
|
+
"runtime_context_compiled",
|
|
9
|
+
"task_classified",
|
|
10
|
+
"query_routed",
|
|
11
|
+
"memory_searched"
|
|
12
|
+
],
|
|
13
|
+
"steps": [
|
|
14
|
+
{
|
|
15
|
+
"id": "load_runtime_context",
|
|
16
|
+
"tool": "aios_compile_runtime_context",
|
|
17
|
+
"args": { "max_modules": 10, "max_decisions": 5, "write": true },
|
|
18
|
+
"on_error": "continue"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "classify",
|
|
22
|
+
"tool": "aios_classify_task",
|
|
23
|
+
"args": { "query": "${input.intent}" },
|
|
24
|
+
"on_error": "abort"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "route",
|
|
28
|
+
"tool": "aios_route_query",
|
|
29
|
+
"args": { "query": "${input.intent}" },
|
|
30
|
+
"on_error": "abort"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "search_memory_for_gap",
|
|
34
|
+
"tool": "aios_search_memory",
|
|
35
|
+
"args": { "query": "${input.intent}", "max_results": 10 },
|
|
36
|
+
"on_error": "continue"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "clarification_gate",
|
|
40
|
+
"tool": "aios_state_set",
|
|
41
|
+
"args": { "path": "rotating.active_focus", "value": "work: clarification on '${input.intent}'" },
|
|
42
|
+
"on_error": "continue",
|
|
43
|
+
"pause_for": {
|
|
44
|
+
"when": "after",
|
|
45
|
+
"reason": "clarification_questions",
|
|
46
|
+
"prompt": "Antes de executar '${input.intent}': há ambiguidades, escopo incerto, ou decisão arquitetural envolvida? Responda 'ok' para prosseguir direto, ou descreva clarificações necessárias.",
|
|
47
|
+
"expected_input": "string"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "build_focused_context",
|
|
52
|
+
"tool": "aios_build_context_package",
|
|
53
|
+
"args": {
|
|
54
|
+
"intent": "${input.intent}",
|
|
55
|
+
"max_modules": 8,
|
|
56
|
+
"write": false
|
|
57
|
+
},
|
|
58
|
+
"on_error": "continue"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "approval_gate",
|
|
62
|
+
"tool": "aios_state_set",
|
|
63
|
+
"args": { "path": "rotating.active_focus", "value": "work: pending approval for '${input.intent}'" },
|
|
64
|
+
"on_error": "continue",
|
|
65
|
+
"pause_for": {
|
|
66
|
+
"when": "after",
|
|
67
|
+
"reason": "plan_approval",
|
|
68
|
+
"prompt": "Plano para '${input.intent}' montado pela LLM com base no runtime-context. Aprovar execução? ('ok' / 'ajustar: <detalhes>' / 'cancelar')",
|
|
69
|
+
"expected_input": "string"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": "validate_post_execution",
|
|
74
|
+
"tool": "aios_lint",
|
|
75
|
+
"args": {},
|
|
76
|
+
"on_error": "continue"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "record_completion",
|
|
80
|
+
"tool": "aios_state_set",
|
|
81
|
+
"args": { "path": "rotating.active_focus", "value": "work: completed '${input.intent}'" },
|
|
82
|
+
"on_error": "continue"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "post_snapshot",
|
|
86
|
+
"tool": "aios_snapshot",
|
|
87
|
+
"args": { "label": "work-${timestamp}" },
|
|
88
|
+
"on_error": "continue"
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stealthos-cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.4",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"bundle-ai": "node scripts/bundle-ai.mjs",
|
|
6
|
+
"prepublishOnly": "node scripts/bundle-ai.mjs"
|
|
7
|
+
},
|
|
4
8
|
"description": "StealthOS CLI — install/manage the StealthOS knowledge base in ~/.stealthos/. Subcommands: install, status, version.",
|
|
5
9
|
"type": "module",
|
|
6
10
|
"bin": {
|
|
@@ -10,6 +14,8 @@
|
|
|
10
14
|
"bin.cjs",
|
|
11
15
|
"bin.mjs",
|
|
12
16
|
"src/",
|
|
17
|
+
"scripts/",
|
|
18
|
+
"ai/",
|
|
13
19
|
"README.md"
|
|
14
20
|
],
|
|
15
21
|
"engines": {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Copies the canonical .ai/ tree from the monorepo root into packages/stealthos-cli/ai/
|
|
3
|
+
// Runs automatically via `prepublishOnly`. Output dir is gitignored.
|
|
4
|
+
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { mkdir, readdir, copyFile, rm, stat } from "node:fs/promises";
|
|
7
|
+
import { join, dirname, resolve } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const PKG_ROOT = resolve(__dirname, "..");
|
|
12
|
+
const REPO_ROOT = resolve(PKG_ROOT, "..", "..");
|
|
13
|
+
const SRC = join(REPO_ROOT, ".ai");
|
|
14
|
+
const DST = join(PKG_ROOT, "ai");
|
|
15
|
+
|
|
16
|
+
const EXCLUDES = new Set([
|
|
17
|
+
"node_modules",
|
|
18
|
+
".runtime",
|
|
19
|
+
"runtime",
|
|
20
|
+
"artifacts",
|
|
21
|
+
"context",
|
|
22
|
+
"snapshots",
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
async function copyDir(src, dst) {
|
|
26
|
+
await mkdir(dst, { recursive: true });
|
|
27
|
+
const entries = await readdir(src, { withFileTypes: true });
|
|
28
|
+
let count = 0;
|
|
29
|
+
for (const e of entries) {
|
|
30
|
+
if (EXCLUDES.has(e.name)) continue;
|
|
31
|
+
const s = join(src, e.name);
|
|
32
|
+
const d = join(dst, e.name);
|
|
33
|
+
if (e.isDirectory()) {
|
|
34
|
+
count += await copyDir(s, d);
|
|
35
|
+
} else if (e.isFile()) {
|
|
36
|
+
await copyFile(s, d);
|
|
37
|
+
count++;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return count;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function main() {
|
|
44
|
+
if (!existsSync(SRC)) {
|
|
45
|
+
console.error(`✖ Source not found: ${SRC}`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
if (existsSync(DST)) {
|
|
49
|
+
await rm(DST, { recursive: true, force: true });
|
|
50
|
+
}
|
|
51
|
+
const n = await copyDir(SRC, DST);
|
|
52
|
+
console.log(`✓ Bundled ${n} files: ${SRC} → ${DST}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
main().catch((e) => {
|
|
56
|
+
console.error("✖ bundle-ai failed:", e.message);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
});
|
package/src/cli.mjs
CHANGED
package/src/commands/install.mjs
CHANGED
|
@@ -5,10 +5,24 @@
|
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { mkdir, writeFile, readFile } from "node:fs/promises";
|
|
7
7
|
import { join } from "node:path";
|
|
8
|
-
import { homedir } from "node:os";
|
|
8
|
+
import { homedir, platform } from "node:os";
|
|
9
|
+
import { spawn } from "node:child_process";
|
|
9
10
|
import { resolveSource } from "../lib/resolve-source.mjs";
|
|
10
11
|
import { copyTree } from "../lib/copy-tree.mjs";
|
|
11
12
|
|
|
13
|
+
function runNpmInstall(cwd) {
|
|
14
|
+
return new Promise((resolve) => {
|
|
15
|
+
const npmCmd = platform() === "win32" ? "npm.cmd" : "npm";
|
|
16
|
+
const child = spawn(npmCmd, ["install", "--silent", "--no-audit", "--no-fund"], {
|
|
17
|
+
cwd,
|
|
18
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
19
|
+
shell: false,
|
|
20
|
+
});
|
|
21
|
+
child.on("close", (code) => resolve(code === 0));
|
|
22
|
+
child.on("error", () => resolve(false));
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
12
26
|
// Paths NOT to copy: runtime-generated outputs + project-specific history.
|
|
13
27
|
// These get freshly initialized per project by the server.
|
|
14
28
|
const DEFAULT_EXCLUDES = [
|
|
@@ -67,6 +81,7 @@ export async function installCommand(flags = {}) {
|
|
|
67
81
|
const home = flags.home ? String(flags.home) : (process.env.STEALTHOS_HOME || join(homedir(), ".stealthos"));
|
|
68
82
|
const source = resolveSource({ flagSource: flags.source });
|
|
69
83
|
const force = !!flags.force;
|
|
84
|
+
const skipServerDeps = !!flags["skip-server-deps"];
|
|
70
85
|
|
|
71
86
|
process.stdout.write(`\n╔══════════════════════════════════════════════╗\n`);
|
|
72
87
|
process.stdout.write(`║ stealthos install ║\n`);
|
|
@@ -110,7 +125,7 @@ export async function installCommand(flags = {}) {
|
|
|
110
125
|
installed_at: new Date().toISOString(),
|
|
111
126
|
installed_from: source,
|
|
112
127
|
source_version: sourceVersion,
|
|
113
|
-
cli_version: "0.1.0-alpha.
|
|
128
|
+
cli_version: "0.1.0-alpha.4",
|
|
114
129
|
};
|
|
115
130
|
await writeFile(join(home, ".stealthos-version.json"), JSON.stringify(versionMarker, null, 2), "utf8");
|
|
116
131
|
|
|
@@ -122,15 +137,24 @@ export async function installCommand(flags = {}) {
|
|
|
122
137
|
process.stdout.write(` • Memory templates: ${templatesWritten}\n`);
|
|
123
138
|
process.stdout.write(` • Versão source: ${sourceVersion}\n`);
|
|
124
139
|
|
|
125
|
-
//
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
140
|
+
// Auto-install server deps (unless --skip-server-deps)
|
|
141
|
+
const serverDir = join(home, "server");
|
|
142
|
+
const serverPkgJson = join(serverDir, "package.json");
|
|
143
|
+
if (existsSync(serverPkgJson) && !existsSync(join(serverDir, "node_modules"))) {
|
|
144
|
+
if (skipServerDeps) {
|
|
145
|
+
process.stdout.write(`\n⚠ Server deps NÃO instaladas (--skip-server-deps).\n`);
|
|
146
|
+
process.stdout.write(` Rode depois: cd "${serverDir}" && npm install\n`);
|
|
147
|
+
} else {
|
|
148
|
+
process.stdout.write(`\n📦 Instalando deps do server (pode levar 30s)...\n`);
|
|
149
|
+
const ok = await runNpmInstall(serverDir);
|
|
150
|
+
if (ok) {
|
|
151
|
+
process.stdout.write(`✓ Server deps instaladas\n`);
|
|
152
|
+
} else {
|
|
153
|
+
process.stdout.write(`⚠ npm install no server falhou. Rode manualmente:\n`);
|
|
154
|
+
process.stdout.write(` cd "${serverDir}" && npm install\n`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
130
157
|
}
|
|
131
158
|
|
|
132
|
-
process.stdout.write(`\
|
|
133
|
-
process.stdout.write(` export STEALTHOS_MODE=hybrid\n`);
|
|
134
|
-
process.stdout.write(` export STEALTHOS_HOME="${home}"\n`);
|
|
135
|
-
process.stdout.write(` node "${join(home, "server", "aios-server.mjs")}" --http\n`);
|
|
159
|
+
process.stdout.write(`\n✓ Tudo pronto. Abra sua IDE no projeto e use /init, /sync ou /work.\n`);
|
|
136
160
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Locate the source .ai/ tree to install from.
|
|
2
|
-
// Strategy:
|
|
3
|
-
// 1. Explicit --source flag
|
|
2
|
+
// Strategy (in order):
|
|
3
|
+
// 1. Explicit --source flag
|
|
4
4
|
// 2. STEALTHOS_SOURCE env var
|
|
5
|
-
// 3.
|
|
6
|
-
// 4.
|
|
5
|
+
// 3. Bundled ai/ inside the published package (preferred for end users)
|
|
6
|
+
// 4. Monorepo discovery: walk up looking for sibling .ai/ (dev mode)
|
|
7
|
+
// 5. Fail loudly
|
|
7
8
|
|
|
8
9
|
import { existsSync } from "node:fs";
|
|
9
10
|
import { resolve, dirname, join } from "node:path";
|
|
@@ -12,22 +13,29 @@ import { fileURLToPath } from "node:url";
|
|
|
12
13
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
14
|
|
|
14
15
|
function resolveAiDir(abs) {
|
|
15
|
-
// Accept either <root> (contains
|
|
16
|
+
// Accept either <root> (contains manifest.json) or <root>/.ai (contains manifest.json) or <root>/ai (bundled)
|
|
16
17
|
if (existsSync(join(abs, "manifest.json"))) return abs;
|
|
17
|
-
const sub
|
|
18
|
-
|
|
18
|
+
for (const sub of [".ai", "ai"]) {
|
|
19
|
+
const candidate = join(abs, sub);
|
|
20
|
+
if (existsSync(join(candidate, "manifest.json"))) return candidate;
|
|
21
|
+
}
|
|
19
22
|
return null;
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
export function resolveSource({ flagSource } = {}) {
|
|
26
|
+
// 1. Explicit --source
|
|
23
27
|
if (flagSource) {
|
|
24
28
|
const abs = resolve(flagSource);
|
|
25
29
|
const ai = resolveAiDir(abs);
|
|
26
30
|
if (!ai) {
|
|
27
|
-
throw new Error(
|
|
31
|
+
throw new Error(
|
|
32
|
+
`--source path does not contain manifest.json (checked ${abs}, ${join(abs, ".ai")}, ${join(abs, "ai")})`,
|
|
33
|
+
);
|
|
28
34
|
}
|
|
29
35
|
return ai;
|
|
30
36
|
}
|
|
37
|
+
|
|
38
|
+
// 2. Env var
|
|
31
39
|
if (process.env.STEALTHOS_SOURCE) {
|
|
32
40
|
const abs = resolve(process.env.STEALTHOS_SOURCE);
|
|
33
41
|
const ai = resolveAiDir(abs);
|
|
@@ -36,7 +44,15 @@ export function resolveSource({ flagSource } = {}) {
|
|
|
36
44
|
}
|
|
37
45
|
return ai;
|
|
38
46
|
}
|
|
39
|
-
|
|
47
|
+
|
|
48
|
+
// 3. Bundled inside the package itself (created by prepublishOnly)
|
|
49
|
+
// __dirname = packages/stealthos-cli/src/lib → ../../ai
|
|
50
|
+
const bundled = resolve(__dirname, "..", "..", "ai");
|
|
51
|
+
if (existsSync(join(bundled, "manifest.json"))) {
|
|
52
|
+
return bundled;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 4. Monorepo dev fallback: walk up from src/lib looking for sibling .ai/
|
|
40
56
|
let dir = __dirname;
|
|
41
57
|
for (let i = 0; i < 6; i++) {
|
|
42
58
|
const candidate = join(dir, ".ai");
|
|
@@ -47,7 +63,8 @@ export function resolveSource({ flagSource } = {}) {
|
|
|
47
63
|
if (parent === dir) break;
|
|
48
64
|
dir = parent;
|
|
49
65
|
}
|
|
66
|
+
|
|
50
67
|
throw new Error(
|
|
51
|
-
"Could not locate source .ai/ tree.
|
|
68
|
+
"Could not locate source .ai/ tree. The CLI should ship with bundled ai/ — reinstall stealthos-cli, or pass --source <path-to-stealthos-repo>.",
|
|
52
69
|
);
|
|
53
70
|
}
|