@aipper/aiws 0.0.28 → 0.0.30
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/README.md +18 -2
- package/bin/aiws.js +2 -2
- package/dist/aiws-package.d.ts +4 -0
- package/dist/aiws-package.js +11 -0
- package/dist/aiws-package.js.map +1 -0
- package/dist/aiws-paths.d.ts +48 -0
- package/dist/aiws-paths.js +129 -0
- package/dist/aiws-paths.js.map +1 -0
- package/dist/backup.d.ts +27 -0
- package/dist/backup.js +125 -0
- package/dist/backup.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +773 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-prompts.d.ts +17 -0
- package/dist/codex-prompts.js +49 -0
- package/dist/codex-prompts.js.map +1 -0
- package/dist/codex-skills.d.ts +17 -0
- package/dist/codex-skills.js +75 -0
- package/dist/codex-skills.js.map +1 -0
- package/dist/commands/change-advice.d.ts +25 -0
- package/dist/commands/change-advice.js +197 -0
- package/dist/commands/change-advice.js.map +1 -0
- package/dist/commands/change-evidence-command.d.ts +29 -0
- package/dist/commands/change-evidence-command.js +213 -0
- package/dist/commands/change-evidence-command.js.map +1 -0
- package/dist/commands/change-evidence-entry.d.ts +16 -0
- package/dist/commands/change-evidence-entry.js +35 -0
- package/dist/commands/change-evidence-entry.js.map +1 -0
- package/dist/commands/change-evidence.d.ts +108 -0
- package/dist/commands/change-evidence.js +341 -0
- package/dist/commands/change-evidence.js.map +1 -0
- package/dist/commands/change-finish.d.ts +71 -0
- package/dist/commands/change-finish.js +387 -0
- package/dist/commands/change-finish.js.map +1 -0
- package/dist/commands/change-git-status.d.ts +22 -0
- package/dist/commands/change-git-status.js +50 -0
- package/dist/commands/change-git-status.js.map +1 -0
- package/dist/commands/change-lifecycle-entry.d.ts +29 -0
- package/{src → dist}/commands/change-lifecycle-entry.js +21 -28
- package/dist/commands/change-lifecycle-entry.js.map +1 -0
- package/dist/commands/change-lifecycle.d.ts +56 -0
- package/dist/commands/change-lifecycle.js +211 -0
- package/dist/commands/change-lifecycle.js.map +1 -0
- package/dist/commands/change-metrics-command.d.ts +12 -0
- package/dist/commands/change-metrics-command.js +110 -0
- package/dist/commands/change-metrics-command.js.map +1 -0
- package/dist/commands/change-next-command.d.ts +18 -0
- package/dist/commands/change-next-command.js +138 -0
- package/dist/commands/change-next-command.js.map +1 -0
- package/dist/commands/change-review-gates.d.ts +107 -0
- package/dist/commands/change-review-gates.js +329 -0
- package/dist/commands/change-review-gates.js.map +1 -0
- package/dist/commands/change-scope-gate.d.ts +21 -0
- package/dist/commands/change-scope-gate.js +32 -0
- package/dist/commands/change-scope-gate.js.map +1 -0
- package/dist/commands/change-start.d.ts +30 -0
- package/dist/commands/change-start.js +91 -0
- package/dist/commands/change-start.js.map +1 -0
- package/dist/commands/change-state-command.d.ts +3 -0
- package/dist/commands/change-state-command.js +32 -0
- package/dist/commands/change-state-command.js.map +1 -0
- package/dist/commands/change-status-command.d.ts +13 -0
- package/dist/commands/change-status-command.js +126 -0
- package/dist/commands/change-status-command.js.map +1 -0
- package/dist/commands/change-status-context.d.ts +58 -0
- package/dist/commands/change-status-context.js +166 -0
- package/dist/commands/change-status-context.js.map +1 -0
- package/dist/commands/change-task-stats.d.ts +24 -0
- package/dist/commands/change-task-stats.js +66 -0
- package/dist/commands/change-task-stats.js.map +1 -0
- package/dist/commands/change-validate-entry.d.ts +17 -0
- package/dist/commands/change-validate-entry.js +44 -0
- package/dist/commands/change-validate-entry.js.map +1 -0
- package/dist/commands/change-validate.d.ts +32 -0
- package/dist/commands/change-validate.js +128 -0
- package/dist/commands/change-validate.js.map +1 -0
- package/dist/commands/change.d.ts +322 -0
- package/dist/commands/change.js +1731 -0
- package/dist/commands/change.js.map +1 -0
- package/dist/commands/codex-install-prompts.d.ts +4 -0
- package/dist/commands/codex-install-prompts.js +68 -0
- package/dist/commands/codex-install-prompts.js.map +1 -0
- package/dist/commands/codex-install-skills.d.ts +4 -0
- package/dist/commands/codex-install-skills.js +74 -0
- package/dist/commands/codex-install-skills.js.map +1 -0
- package/dist/commands/codex-status-prompts.d.ts +4 -0
- package/dist/commands/codex-status-prompts.js +44 -0
- package/dist/commands/codex-status-prompts.js.map +1 -0
- package/dist/commands/codex-status-skills.d.ts +4 -0
- package/dist/commands/codex-status-skills.js +54 -0
- package/dist/commands/codex-status-skills.js.map +1 -0
- package/dist/commands/codex-uninstall-prompts.d.ts +4 -0
- package/dist/commands/codex-uninstall-prompts.js +51 -0
- package/dist/commands/codex-uninstall-prompts.js.map +1 -0
- package/dist/commands/codex-uninstall-skills.d.ts +4 -0
- package/dist/commands/codex-uninstall-skills.js +59 -0
- package/dist/commands/codex-uninstall-skills.js.map +1 -0
- package/dist/commands/dashboard.d.ts +222 -0
- package/dist/commands/dashboard.js +193 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/hooks-install.d.ts +4 -0
- package/dist/commands/hooks-install.js +90 -0
- package/dist/commands/hooks-install.js.map +1 -0
- package/dist/commands/hooks-status.d.ts +4 -0
- package/dist/commands/hooks-status.js +89 -0
- package/dist/commands/hooks-status.js.map +1 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +100 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/opencode-auto.d.ts +11 -0
- package/dist/commands/opencode-auto.js +158 -0
- package/dist/commands/opencode-auto.js.map +1 -0
- package/dist/commands/opencode-status.d.ts +4 -0
- package/dist/commands/opencode-status.js +75 -0
- package/dist/commands/opencode-status.js.map +1 -0
- package/dist/commands/opencode-supervise.d.ts +24 -0
- package/dist/commands/opencode-supervise.js +188 -0
- package/dist/commands/opencode-supervise.js.map +1 -0
- package/dist/commands/rollback.d.ts +4 -0
- package/dist/commands/rollback.js +12 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/update.d.ts +4 -0
- package/dist/commands/update.js +212 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate.d.ts +4 -0
- package/dist/commands/validate.js +222 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/ws-commit.d.ts +5 -0
- package/dist/commands/ws-commit.js +39 -0
- package/dist/commands/ws-commit.js.map +1 -0
- package/dist/commands/ws-deliver.d.ts +5 -0
- package/dist/commands/ws-deliver.js +59 -0
- package/dist/commands/ws-deliver.js.map +1 -0
- package/dist/commands/ws-finish.d.ts +5 -0
- package/dist/commands/ws-finish.js +142 -0
- package/dist/commands/ws-finish.js.map +1 -0
- package/dist/commands/ws-handoff.d.ts +5 -0
- package/dist/commands/ws-handoff.js +35 -0
- package/dist/commands/ws-handoff.js.map +1 -0
- package/dist/commands/ws-migrate.d.ts +5 -0
- package/dist/commands/ws-migrate.js +41 -0
- package/dist/commands/ws-migrate.js.map +1 -0
- package/dist/commands/ws-plan-verify.d.ts +5 -0
- package/dist/commands/ws-plan-verify.js +38 -0
- package/dist/commands/ws-plan-verify.js.map +1 -0
- package/dist/commands/ws-pull.d.ts +5 -0
- package/dist/commands/ws-pull.js +26 -0
- package/dist/commands/ws-pull.js.map +1 -0
- package/dist/commands/ws-push.d.ts +5 -0
- package/dist/commands/ws-push.js +68 -0
- package/dist/commands/ws-push.js.map +1 -0
- package/dist/commands/ws-submodule-setup.d.ts +5 -0
- package/dist/commands/ws-submodule-setup.js +55 -0
- package/dist/commands/ws-submodule-setup.js.map +1 -0
- package/dist/commands/ws-verify-before-complete.d.ts +5 -0
- package/dist/commands/ws-verify-before-complete.js +35 -0
- package/dist/commands/ws-verify-before-complete.js.map +1 -0
- package/dist/dashboard/app.d.ts +1 -0
- package/dist/dashboard/app.js +370 -0
- package/dist/dashboard/app.js.map +1 -0
- package/dist/delegation/cli.d.ts +6 -0
- package/dist/delegation/cli.js +14 -0
- package/dist/delegation/cli.js.map +1 -0
- package/dist/delegation/index.d.ts +35 -0
- package/dist/delegation/index.js +118 -0
- package/dist/delegation/index.js.map +1 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +11 -0
- package/dist/errors.js.map +1 -0
- package/dist/exec.d.ts +9 -0
- package/dist/exec.js +22 -0
- package/dist/exec.js.map +1 -0
- package/dist/fs.d.ts +9 -0
- package/dist/fs.js +62 -0
- package/dist/fs.js.map +1 -0
- package/dist/governance.d.ts +10 -0
- package/dist/governance.js +135 -0
- package/dist/governance.js.map +1 -0
- package/dist/hash.d.ts +3 -0
- package/dist/hash.js +13 -0
- package/dist/hash.js.map +1 -0
- package/dist/hooks/deploy-claude.d.ts +13 -0
- package/dist/hooks/deploy-claude.js +67 -0
- package/dist/hooks/deploy-claude.js.map +1 -0
- package/dist/journal.d.ts +22 -0
- package/dist/journal.js +112 -0
- package/dist/journal.js.map +1 -0
- package/dist/json-schema-lite.d.ts +22 -0
- package/dist/json-schema-lite.js +148 -0
- package/dist/json-schema-lite.js.map +1 -0
- package/dist/managed-blocks.d.ts +24 -0
- package/dist/managed-blocks.js +84 -0
- package/dist/managed-blocks.js.map +1 -0
- package/dist/manifest.d.ts +24 -0
- package/dist/manifest.js +145 -0
- package/dist/manifest.js.map +1 -0
- package/dist/opencode-env.d.ts +62 -0
- package/dist/opencode-env.js +178 -0
- package/dist/opencode-env.js.map +1 -0
- package/dist/path-utils.d.ts +2 -0
- package/dist/path-utils.js +8 -0
- package/dist/path-utils.js.map +1 -0
- package/dist/spec.d.ts +17 -0
- package/dist/spec.js +174 -0
- package/dist/spec.js.map +1 -0
- package/dist/template.d.ts +20 -0
- package/dist/template.js +123 -0
- package/dist/template.js.map +1 -0
- package/dist/workspace.d.ts +4 -0
- package/dist/workspace.js +19 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +11 -3
- package/src/aiws-package.js +0 -15
- package/src/backup.js +0 -149
- package/src/cli.js +0 -647
- package/src/codex-prompts.js +0 -74
- package/src/codex-skills.js +0 -111
- package/src/commands/change-advice.js +0 -200
- package/src/commands/change-evidence-command.js +0 -242
- package/src/commands/change-evidence-entry.js +0 -40
- package/src/commands/change-evidence.js +0 -340
- package/src/commands/change-finish.js +0 -484
- package/src/commands/change-git-status.js +0 -53
- package/src/commands/change-lifecycle.js +0 -236
- package/src/commands/change-metrics-command.js +0 -110
- package/src/commands/change-next-command.js +0 -129
- package/src/commands/change-review-gates.js +0 -315
- package/src/commands/change-scope-gate.js +0 -34
- package/src/commands/change-start.js +0 -120
- package/src/commands/change-state-command.js +0 -40
- package/src/commands/change-status-command.js +0 -134
- package/src/commands/change-status-context.js +0 -202
- package/src/commands/change-task-stats.js +0 -64
- package/src/commands/change-validate-entry.js +0 -45
- package/src/commands/change-validate.js +0 -127
- package/src/commands/change.js +0 -2087
- package/src/commands/codex-install-prompts.js +0 -68
- package/src/commands/codex-install-skills.js +0 -74
- package/src/commands/codex-status-prompts.js +0 -55
- package/src/commands/codex-status-skills.js +0 -63
- package/src/commands/codex-uninstall-prompts.js +0 -55
- package/src/commands/codex-uninstall-skills.js +0 -62
- package/src/commands/dashboard.js +0 -205
- package/src/commands/hooks-install.js +0 -92
- package/src/commands/hooks-status.js +0 -95
- package/src/commands/init.js +0 -93
- package/src/commands/opencode-status.js +0 -61
- package/src/commands/rollback.js +0 -13
- package/src/commands/update.js +0 -133
- package/src/commands/validate.js +0 -222
- package/src/dashboard/app.js +0 -371
- package/src/errors.js +0 -15
- package/src/exec.js +0 -34
- package/src/fs.js +0 -91
- package/src/governance.js +0 -159
- package/src/hash.js +0 -25
- package/src/json-schema-lite.js +0 -164
- package/src/managed-blocks.js +0 -131
- package/src/manifest.js +0 -153
- package/src/opencode-env.js +0 -76
- package/src/path-utils.js +0 -20
- package/src/spec.js +0 -195
- package/src/template.js +0 -187
- package/src/workspace.js +0 -23
- /package/{src → dist}/dashboard/index.html +0 -0
- /package/{src → dist}/dashboard/style.css +0 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { loadTemplate } from "../spec.js";
|
|
4
|
+
import { loadAiwsPackage } from "../aiws-package.js";
|
|
5
|
+
import { resolveWorkspaceRoot } from "../workspace.js";
|
|
6
|
+
import { readText, pathExists } from "../fs.js";
|
|
7
|
+
import { UserError } from "../errors.js";
|
|
8
|
+
import { normalizeNewlines } from "../hash.js";
|
|
9
|
+
import { findManagedBlock } from "../managed-blocks.js";
|
|
10
|
+
import { BackupSession } from "../backup.js";
|
|
11
|
+
import { normalizeRel, joinRel } from "../path-utils.js";
|
|
12
|
+
import { copyTemplateFileToWorkspace, applyManagedBlocksFromTemplate } from "../template.js";
|
|
13
|
+
import { detectLegacyWorkspaceTemplateId, writeWorkspaceManifest } from "../manifest.js";
|
|
14
|
+
import { deployClaudeHooks } from "../hooks/deploy-claude.js";
|
|
15
|
+
import { DIR_MIGRATION_MAP, FILE_MIGRATION_MAP } from "../aiws-paths.js";
|
|
16
|
+
/**
|
|
17
|
+
* Rename a file or directory, falling back to copy+delete when renaming
|
|
18
|
+
* across different filesystems (EXDEV).
|
|
19
|
+
*/
|
|
20
|
+
async function renameOrCopy(src, dst) {
|
|
21
|
+
try {
|
|
22
|
+
await fs.rename(src, dst);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
if (err.code === "EXDEV") {
|
|
26
|
+
await fs.cp(src, dst, { recursive: true, force: true });
|
|
27
|
+
await fs.rm(src, { recursive: true, force: true });
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Move old root-level AIWS artifacts into `.aiws/`.
|
|
36
|
+
* Skips if source doesn't exist or target already exists.
|
|
37
|
+
* Returns the number of items moved.
|
|
38
|
+
*/
|
|
39
|
+
async function migrateOldLayout(workspaceRoot, backup) {
|
|
40
|
+
let count = 0;
|
|
41
|
+
for (const [srcRel, dstRel] of Object.entries(DIR_MIGRATION_MAP)) {
|
|
42
|
+
const src = path.join(workspaceRoot, srcRel);
|
|
43
|
+
const dst = path.join(workspaceRoot, dstRel);
|
|
44
|
+
if (!(await pathExists(src)))
|
|
45
|
+
continue;
|
|
46
|
+
if (await pathExists(dst)) {
|
|
47
|
+
console.log(` skip ${srcRel} → ${dstRel} (target already exists)`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
await backup.recordFile(srcRel, { recordMissing: true });
|
|
51
|
+
await fs.mkdir(path.dirname(dst), { recursive: true });
|
|
52
|
+
await renameOrCopy(src, dst);
|
|
53
|
+
count++;
|
|
54
|
+
}
|
|
55
|
+
for (const [srcRel, dstRel] of Object.entries(FILE_MIGRATION_MAP)) {
|
|
56
|
+
const src = path.join(workspaceRoot, srcRel);
|
|
57
|
+
const dst = path.join(workspaceRoot, dstRel);
|
|
58
|
+
if (!(await pathExists(src)))
|
|
59
|
+
continue;
|
|
60
|
+
if (await pathExists(dst)) {
|
|
61
|
+
console.log(` skip ${srcRel} → ${dstRel} (target already exists)`);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
await backup.recordFile(srcRel, { recordMissing: true });
|
|
65
|
+
await fs.mkdir(path.dirname(dst), { recursive: true });
|
|
66
|
+
await renameOrCopy(src, dst);
|
|
67
|
+
count++;
|
|
68
|
+
}
|
|
69
|
+
return count;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* @param {{ targetPath: string }} options
|
|
73
|
+
*/
|
|
74
|
+
export async function updateCommand(options) {
|
|
75
|
+
const workspaceRoot = await resolveWorkspaceRoot(options.targetPath, { create: false });
|
|
76
|
+
const aiws = await loadAiwsPackage();
|
|
77
|
+
const manifestPath = path.join(workspaceRoot, ".aiws", "manifest.json");
|
|
78
|
+
const hasManifest = await pathExists(manifestPath);
|
|
79
|
+
const legacyTemplateId = !hasManifest ? await detectLegacyWorkspaceTemplateId(workspaceRoot) : null;
|
|
80
|
+
const legacyMigration = !hasManifest && Boolean(legacyTemplateId);
|
|
81
|
+
if (!hasManifest && !legacyTemplateId) {
|
|
82
|
+
throw new UserError("Missing .aiws/manifest.json. Run `aiws init` first.");
|
|
83
|
+
}
|
|
84
|
+
const stored = hasManifest
|
|
85
|
+
? JSON.parse(await readText(manifestPath))
|
|
86
|
+
: { template_id: legacyTemplateId, installed_at: "", tools: [], managed: [] };
|
|
87
|
+
const templateId = String(stored.template_id || legacyTemplateId || "workspace");
|
|
88
|
+
const tpl = await loadTemplate(templateId);
|
|
89
|
+
const storedManagedByPath = new Map((Array.isArray(stored.managed) ? stored.managed : [])
|
|
90
|
+
.filter((entry) => entry && typeof entry === "object")
|
|
91
|
+
.map((entry) => [normalizeRel(String(entry.path || "")), entry]));
|
|
92
|
+
const defaults = tpl.manifest.defaults || {};
|
|
93
|
+
const defaultTools = Array.isArray(defaults.tools) ? defaults.tools.map(String) : ["claude", "opencode", "codex"];
|
|
94
|
+
const allowedTools = new Set(defaultTools);
|
|
95
|
+
const update = tpl.manifest.update || {};
|
|
96
|
+
const replaceFiles = (update.replace_file || []).map(normalizeRel);
|
|
97
|
+
const managedBlocks = update.managed_blocks && typeof update.managed_blocks === "object" ? update.managed_blocks : {};
|
|
98
|
+
// Preflight: existing managed-block files must be intact.
|
|
99
|
+
// Missing files that were not previously managed are treated as newly introduced
|
|
100
|
+
// template surfaces and will be created during applyManagedBlocksFromTemplate.
|
|
101
|
+
for (const [fileRelRaw, blockIdsRaw] of Object.entries(managedBlocks)) {
|
|
102
|
+
const fileRel = normalizeRel(fileRelRaw);
|
|
103
|
+
const abs = joinRel(workspaceRoot, fileRel);
|
|
104
|
+
const hadManagedBefore = storedManagedByPath.has(fileRel);
|
|
105
|
+
if (!(await pathExists(abs))) {
|
|
106
|
+
if (hadManagedBefore) {
|
|
107
|
+
throw new UserError("Managed block file missing; run `aiws init` or restore the file.", { details: `Missing: ${fileRel}` });
|
|
108
|
+
}
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const text = normalizeNewlines(await readText(abs));
|
|
112
|
+
const ids = Array.isArray(blockIdsRaw) ? blockIdsRaw.map(String) : [];
|
|
113
|
+
for (const id of ids) {
|
|
114
|
+
if (!findManagedBlock(text, id)) {
|
|
115
|
+
if (legacyMigration) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
throw new UserError("Managed block markers are missing or broken; refusing to update.", {
|
|
119
|
+
details: `File: ${fileRel}\nBlock: ${id}\nHint: re-run \`aiws init\` or repair markers manually.`,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const removeFiles = (update.remove || []).map(normalizeRel);
|
|
125
|
+
const backup = new BackupSession({ workspaceRoot, operation: "update" });
|
|
126
|
+
// Backup every file we might touch (including missing, for rollback deletions).
|
|
127
|
+
await backup.recordFile(".aiws/manifest.json", { recordMissing: true });
|
|
128
|
+
for (const f of replaceFiles)
|
|
129
|
+
await backup.recordFile(f, { recordMissing: true });
|
|
130
|
+
for (const f of Object.keys(managedBlocks))
|
|
131
|
+
await backup.recordFile(f, { recordMissing: true });
|
|
132
|
+
for (const f of removeFiles)
|
|
133
|
+
await backup.recordFile(f, undefined);
|
|
134
|
+
await backup.finalize({ extra: { template_id: tpl.templateId } });
|
|
135
|
+
const migratedCount = await migrateOldLayout(workspaceRoot, backup);
|
|
136
|
+
if (migratedCount > 0) {
|
|
137
|
+
console.log(` migrated ${migratedCount} old AIWS artifact(s) into .aiws/`);
|
|
138
|
+
}
|
|
139
|
+
// Remove deprecated files (backed up above; restorable via `aiws rollback`).
|
|
140
|
+
let removedCount = 0;
|
|
141
|
+
for (const rel of removeFiles) {
|
|
142
|
+
if (!rel)
|
|
143
|
+
continue;
|
|
144
|
+
const abs = joinRel(workspaceRoot, rel);
|
|
145
|
+
if (await pathExists(abs)) {
|
|
146
|
+
await fs.rm(abs, { force: true });
|
|
147
|
+
removedCount++;
|
|
148
|
+
// Remove empty parent directory (safe: rmdir fails on non-empty).
|
|
149
|
+
try {
|
|
150
|
+
await fs.rmdir(path.dirname(abs));
|
|
151
|
+
}
|
|
152
|
+
catch { /* non-empty or gone */ }
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (removedCount > 0) {
|
|
156
|
+
console.log(` removed ${removedCount} deprecated file(s)`);
|
|
157
|
+
}
|
|
158
|
+
// Replace files (except manifest, generated later).
|
|
159
|
+
for (const rel of replaceFiles) {
|
|
160
|
+
if (!rel || rel === ".aiws/manifest.json")
|
|
161
|
+
continue;
|
|
162
|
+
await copyTemplateFileToWorkspace({
|
|
163
|
+
templateDir: tpl.templateDir,
|
|
164
|
+
workspaceRoot,
|
|
165
|
+
relPosix: rel,
|
|
166
|
+
chmod: rel.startsWith(".githooks/") ? 0o755 : undefined,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
// Update managed blocks only (do not insert missing blocks).
|
|
170
|
+
for (const [fileRelRaw, blockIdsRaw] of Object.entries(managedBlocks)) {
|
|
171
|
+
const fileRel = normalizeRel(fileRelRaw);
|
|
172
|
+
const ids = Array.isArray(blockIdsRaw) ? blockIdsRaw.map(String) : [];
|
|
173
|
+
await applyManagedBlocksFromTemplate({
|
|
174
|
+
templateDir: tpl.templateDir,
|
|
175
|
+
workspaceRoot,
|
|
176
|
+
fileRel,
|
|
177
|
+
blockIds: ids,
|
|
178
|
+
insertIfMissing: legacyMigration,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
const now = new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
182
|
+
const installedAt = String(stored.installed_at || now);
|
|
183
|
+
const storedTools = Array.isArray(stored.tools) ? stored.tools.map(String).filter((tool) => allowedTools.has(tool)) : [];
|
|
184
|
+
const tools = storedTools.length > 0 ? storedTools : defaultTools;
|
|
185
|
+
await writeWorkspaceManifest({
|
|
186
|
+
workspaceRoot,
|
|
187
|
+
templateId: tpl.templateId,
|
|
188
|
+
specVersion: tpl.specVersion,
|
|
189
|
+
aiwsVersion: aiws.version,
|
|
190
|
+
installedAt,
|
|
191
|
+
updatedAt: now,
|
|
192
|
+
tools,
|
|
193
|
+
templateManifest: tpl.manifest,
|
|
194
|
+
});
|
|
195
|
+
const pluginEntries = (tpl.manifest.required || [])
|
|
196
|
+
.filter((rel) => rel.startsWith(".opencode/plugins/") && rel.endsWith(".js"));
|
|
197
|
+
for (const rel of pluginEntries) {
|
|
198
|
+
await copyTemplateFileToWorkspace({
|
|
199
|
+
templateDir: tpl.templateDir,
|
|
200
|
+
workspaceRoot,
|
|
201
|
+
relPosix: rel,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
if (tools.includes("claude")) {
|
|
205
|
+
await deployClaudeHooks({ force: true });
|
|
206
|
+
}
|
|
207
|
+
if (legacyMigration) {
|
|
208
|
+
console.log(` migrated legacy AIWS workspace: generated .aiws/manifest.json for template=${legacyTemplateId}`);
|
|
209
|
+
}
|
|
210
|
+
console.log(`✓ aiws update: ${workspaceRoot}`);
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,+BAA+B,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEzE;;;GAGG;AACH,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,GAAW;IAClD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzB,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACxD,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,gBAAgB,CAAC,aAAqB,EAAE,MAAqB;IAC1E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;YAAE,SAAS;QACvC,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,MAAM,MAAM,0BAA0B,CAAC,CAAC;YACpE,SAAS;QACX,CAAC;QACD,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,MAAM,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7B,KAAK,EAAE,CAAC;IACV,CAAC;IACD,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAClE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;YAAE,SAAS;QACvC,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,MAAM,MAAM,0BAA0B,CAAC,CAAC;YACpE,SAAS;QACX,CAAC;QACD,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,MAAM,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7B,KAAK,EAAE,CAAC;IACV,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAY;IAC9C,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACxF,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAC;IAErC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IACxE,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC;IACnD,MAAM,gBAAgB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,+BAA+B,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpG,MAAM,eAAe,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAClE,IAAI,CAAC,WAAW,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtC,MAAM,IAAI,SAAS,CAAC,qDAAqD,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,MAAM,GAAG,WAAW;QACxB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC1C,CAAC,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAChF,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,IAAI,gBAAgB,IAAI,WAAW,CAAC,CAAC;IACjF,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,mBAAmB,GAAG,IAAI,GAAG,CACjC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC;SAC1D,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CACxE,CAAC;IACF,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC;IAC7C,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAClH,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;IACzC,MAAM,YAAY,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,MAAM,CAAC,cAAc,IAAI,OAAO,MAAM,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IAEtH,0DAA0D;IAC1D,iFAAiF;IACjF,+EAA+E;IAC/E,KAAK,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QACtE,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC7B,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,IAAI,SAAS,CAAC,kEAAkE,EAAE,EAAE,OAAO,EAAE,YAAY,OAAO,EAAE,EAAE,CAAC,CAAC;YAC9H,CAAC;YACD,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;gBAChC,IAAI,eAAe,EAAE,CAAC;oBACpB,SAAS;gBACX,CAAC;gBACD,MAAM,IAAI,SAAS,CAAC,kEAAkE,EAAE;oBACtF,OAAO,EAAE,SAAS,OAAO,YAAY,EAAE,0DAA0D;iBAClG,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAE5D,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzE,gFAAgF;IAChF,MAAM,MAAM,CAAC,UAAU,CAAC,qBAAqB,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,KAAK,MAAM,CAAC,IAAI,YAAY;QAAE,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;QAAE,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAChG,KAAK,MAAM,CAAC,IAAI,WAAW;QAAE,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACnE,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAElE,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACpE,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,cAAc,aAAa,mCAAmC,CAAC,CAAC;IAC9E,CAAC;IAED,6EAA6E;IAC7E,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QACxC,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAClC,YAAY,EAAE,CAAC;YACf,kEAAkE;YAClE,IAAI,CAAC;gBAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,uBAAuB,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IACD,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,aAAa,YAAY,qBAAqB,CAAC,CAAC;IAC9D,CAAC;IAED,oDAAoD;IACpD,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,qBAAqB;YAAE,SAAS;QACpD,MAAM,2BAA2B,CAAC;YAChC,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,aAAa;YACb,QAAQ,EAAE,GAAG;YACb,KAAK,EAAE,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;SACxD,CAAC,CAAC;IACL,CAAC;IAED,6DAA6D;IAC7D,KAAK,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QACtE,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,MAAM,8BAA8B,CAAC;YACnC,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,aAAa;YACb,OAAO;YACP,QAAQ,EAAE,GAAG;YACb,eAAe,EAAE,eAAe;SACjC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,GAAG,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9H,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;IAElE,MAAM,sBAAsB,CAAC;QAC3B,aAAa;QACb,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,WAAW,EAAE,IAAI,CAAC,OAAO;QACzB,WAAW;QACX,SAAS,EAAE,GAAG;QACd,KAAK;QACL,gBAAgB,EAAE,GAAG,CAAC,QAAQ;KAC/B,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC;SAChD,MAAM,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,oBAAoB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACxF,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,MAAM,2BAA2B,CAAC;YAChC,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,aAAa;YACb,QAAQ,EAAE,GAAG;SACd,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,iBAAiB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,gFAAgF,gBAAgB,EAAE,CAAC,CAAC;IAClH,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,kBAAkB,aAAa,EAAE,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { loadTemplate } from "../spec.js";
|
|
3
|
+
import { resolveWorkspaceRoot } from "../workspace.js";
|
|
4
|
+
import { ensureDir, pathExists, readText, writeText } from "../fs.js";
|
|
5
|
+
import { UserError } from "../errors.js";
|
|
6
|
+
import { detectLegacyWorkspaceTemplateId, validateDrift } from "../manifest.js";
|
|
7
|
+
import { runCommand } from "../exec.js";
|
|
8
|
+
import { expandManifestEntries } from "../template.js";
|
|
9
|
+
import { loadAiwsPackage } from "../aiws-package.js";
|
|
10
|
+
/**
|
|
11
|
+
* Enforce deterministic submodule branch policy:
|
|
12
|
+
* - If `.gitmodules` exists and declares submodules, each submodule must declare `submodule.<name>.branch`.
|
|
13
|
+
* - This avoids guessing which branch to attach/push for workflows like ws-pull/ws-finish.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} workspaceRoot
|
|
16
|
+
*/
|
|
17
|
+
async function validateSubmoduleBranchPolicy(workspaceRoot) {
|
|
18
|
+
const gitmodules = path.join(workspaceRoot, ".gitmodules");
|
|
19
|
+
if (!(await pathExists(gitmodules)))
|
|
20
|
+
return;
|
|
21
|
+
const list = await runCommand("git", ["config", "--file", ".gitmodules", "--get-regexp", "^submodule\\..*\\.path$"], {
|
|
22
|
+
cwd: workspaceRoot,
|
|
23
|
+
});
|
|
24
|
+
if (list.code !== 0) {
|
|
25
|
+
// `.gitmodules` exists but no submodule path entries: treat as ok.
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
/** @type {Array<{ name: string, path: string }>} */
|
|
29
|
+
const subs = [];
|
|
30
|
+
for (const line of String(list.stdout || "").split("\n")) {
|
|
31
|
+
const t = line.trim();
|
|
32
|
+
if (!t)
|
|
33
|
+
continue;
|
|
34
|
+
const idx = t.indexOf(" ");
|
|
35
|
+
if (idx <= 0)
|
|
36
|
+
continue;
|
|
37
|
+
const key = t.slice(0, idx).trim();
|
|
38
|
+
const subPath = t.slice(idx + 1).trim();
|
|
39
|
+
const m = key.match(/^submodule\.(.+)\.path$/);
|
|
40
|
+
if (!m)
|
|
41
|
+
continue;
|
|
42
|
+
const name = m[1] || "";
|
|
43
|
+
if (!name || !subPath)
|
|
44
|
+
continue;
|
|
45
|
+
subs.push({ name, path: subPath });
|
|
46
|
+
}
|
|
47
|
+
if (subs.length === 0)
|
|
48
|
+
return;
|
|
49
|
+
/** @type {Array<{ name: string, path: string }>} */
|
|
50
|
+
const missing = [];
|
|
51
|
+
for (const s of subs) {
|
|
52
|
+
const br = await runCommand("git", ["config", "--file", ".gitmodules", "--get", `submodule.${s.name}.branch`], {
|
|
53
|
+
cwd: workspaceRoot,
|
|
54
|
+
});
|
|
55
|
+
if (br.code !== 0 || !String(br.stdout || "").trim()) {
|
|
56
|
+
missing.push(s);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (missing.length > 0) {
|
|
60
|
+
const lines = missing.map((m) => `- ${m.name} (${m.path}): missing submodule.${m.name}.branch`);
|
|
61
|
+
const hints = missing
|
|
62
|
+
.slice(0, 8)
|
|
63
|
+
.map((m) => `git submodule set-branch --branch main ${m.path}`)
|
|
64
|
+
.join("\n");
|
|
65
|
+
throw new UserError("Submodule branch policy failed: missing `.gitmodules` branch config.", {
|
|
66
|
+
details: `${lines.join("\n")}\n\n` +
|
|
67
|
+
"Fix:\n" +
|
|
68
|
+
"- Run `ws-submodule-setup` (recommended), or set per submodule:\n" +
|
|
69
|
+
`${hints}\n\n` +
|
|
70
|
+
"Then commit `.gitmodules` in the superproject.",
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* @param {string | undefined} v
|
|
76
|
+
*/
|
|
77
|
+
function envFlag(v) {
|
|
78
|
+
const s = String(v || "")
|
|
79
|
+
.trim()
|
|
80
|
+
.toLowerCase();
|
|
81
|
+
return s === "1" || s === "true" || s === "yes" || s === "y" || s === "on";
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* @returns {string} e.g. 20260204-140026Z
|
|
85
|
+
*/
|
|
86
|
+
function nowStampUtc() {
|
|
87
|
+
const d = new Date();
|
|
88
|
+
const y = String(d.getUTCFullYear());
|
|
89
|
+
const m = String(d.getUTCMonth() + 1).padStart(2, "0");
|
|
90
|
+
const day = String(d.getUTCDate()).padStart(2, "0");
|
|
91
|
+
const hh = String(d.getUTCHours()).padStart(2, "0");
|
|
92
|
+
const mm = String(d.getUTCMinutes()).padStart(2, "0");
|
|
93
|
+
const ss = String(d.getUTCSeconds()).padStart(2, "0");
|
|
94
|
+
const ms = String(d.getUTCMilliseconds()).padStart(3, "0");
|
|
95
|
+
return `${y}${m}${day}-${hh}${mm}${ss}${ms}Z`;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* @returns {string} e.g. 2026-01-28T14:00:26Z
|
|
99
|
+
*/
|
|
100
|
+
function nowIsoUtc() {
|
|
101
|
+
return new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* @param {any} error
|
|
105
|
+
* @returns {{ name: string, message: string, details?: string } | null}
|
|
106
|
+
*/
|
|
107
|
+
function serializeError(error) {
|
|
108
|
+
if (!error)
|
|
109
|
+
return null;
|
|
110
|
+
if (error instanceof UserError) {
|
|
111
|
+
return { name: error.name, message: error.message, details: error.details };
|
|
112
|
+
}
|
|
113
|
+
if (error instanceof Error) {
|
|
114
|
+
return { name: error.name, message: error.message };
|
|
115
|
+
}
|
|
116
|
+
return { name: "Error", message: String(error) };
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* @param {{ targetPath: string, stamp?: boolean }} options
|
|
120
|
+
*/
|
|
121
|
+
export async function validateCommand(options) {
|
|
122
|
+
const stampEnabled = options.stamp === true || envFlag(process.env.AIWS_VALIDATE_STAMP);
|
|
123
|
+
const startedAt = nowIsoUtc();
|
|
124
|
+
const startedTs = Math.floor(Date.now() / 1000);
|
|
125
|
+
let workspaceRoot = "";
|
|
126
|
+
let templateId = "";
|
|
127
|
+
let specVersion = "";
|
|
128
|
+
let aiwsVersion = "";
|
|
129
|
+
let status = /** @type {"ok" | "error"} */ ("ok");
|
|
130
|
+
let exitCode = 0;
|
|
131
|
+
let err = null;
|
|
132
|
+
let stampPath = "";
|
|
133
|
+
try {
|
|
134
|
+
workspaceRoot = await resolveWorkspaceRoot(options.targetPath, { create: false });
|
|
135
|
+
const aiws = await loadAiwsPackage();
|
|
136
|
+
aiwsVersion = aiws.version;
|
|
137
|
+
const manifestPath = path.join(workspaceRoot, ".aiws", "manifest.json");
|
|
138
|
+
if (!(await pathExists(manifestPath))) {
|
|
139
|
+
const legacyTemplateId = await detectLegacyWorkspaceTemplateId(workspaceRoot);
|
|
140
|
+
if (legacyTemplateId) {
|
|
141
|
+
throw new UserError("Missing .aiws/manifest.json in a legacy AIWS workspace.", {
|
|
142
|
+
details: "This workspace looks like an older AIWS install. Run `aiws update .` once to generate the manifest, then rerun `aiws validate`.",
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
throw new UserError("Missing .aiws/manifest.json. Run `aiws init` first.");
|
|
146
|
+
}
|
|
147
|
+
const stored = JSON.parse(await readText(manifestPath));
|
|
148
|
+
templateId = String(stored.template_id || "workspace");
|
|
149
|
+
const tpl = await loadTemplate(templateId);
|
|
150
|
+
specVersion = tpl.specVersion;
|
|
151
|
+
// Required files/dirs.
|
|
152
|
+
const required = await expandManifestEntries(tpl.templateDir, tpl.manifest.required || []);
|
|
153
|
+
/** @type {string[]} */
|
|
154
|
+
const missing = [];
|
|
155
|
+
for (const rel of required) {
|
|
156
|
+
const abs = path.join(workspaceRoot, ...String(rel).split("/"));
|
|
157
|
+
if (!(await pathExists(abs)))
|
|
158
|
+
missing.push(rel);
|
|
159
|
+
}
|
|
160
|
+
if (missing.length > 0) {
|
|
161
|
+
throw new UserError("Missing required files.", { details: missing.join("\n") });
|
|
162
|
+
}
|
|
163
|
+
// Drift detection.
|
|
164
|
+
await validateDrift({ workspaceRoot, storedManifest: stored, templateManifest: tpl.manifest });
|
|
165
|
+
// Submodule branch policy (deterministic workflow; avoids guessing target branches).
|
|
166
|
+
await validateSubmoduleBranchPolicy(workspaceRoot);
|
|
167
|
+
// python3 gate.
|
|
168
|
+
const py = await runCommand("python3", ["--version"], { cwd: workspaceRoot });
|
|
169
|
+
if (py.code !== 0) {
|
|
170
|
+
throw new UserError("python3 is required for validate.", { details: py.stderr || py.stdout });
|
|
171
|
+
}
|
|
172
|
+
// Required gate scripts.
|
|
173
|
+
const wsCheck = await runCommand("python3", [".aiws/tools/ws_change_check.py", "--strict"], { cwd: workspaceRoot });
|
|
174
|
+
if (wsCheck.code !== 0) {
|
|
175
|
+
throw new UserError("change gate failed.", { details: wsCheck.stderr || wsCheck.stdout });
|
|
176
|
+
}
|
|
177
|
+
const reqCheck = await runCommand("python3", [".aiws/tools/requirements_contract.py", "validate"], { cwd: workspaceRoot });
|
|
178
|
+
if (reqCheck.code !== 0) {
|
|
179
|
+
throw new UserError("requirements contract gate failed.", { details: reqCheck.stderr || reqCheck.stdout });
|
|
180
|
+
}
|
|
181
|
+
console.log(`✓ aiws validate: ${workspaceRoot}`);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
status = "error";
|
|
185
|
+
err = serializeError(error);
|
|
186
|
+
if (error instanceof UserError) {
|
|
187
|
+
exitCode = error.exitCode;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
exitCode = 1;
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
if (stampEnabled && workspaceRoot) {
|
|
196
|
+
try {
|
|
197
|
+
const stampDir = path.join(workspaceRoot, ".aiws", "tmp", "aiws-validate");
|
|
198
|
+
await ensureDir(stampDir);
|
|
199
|
+
stampPath = path.join(stampDir, `${nowStampUtc()}.json`);
|
|
200
|
+
const stamp = {
|
|
201
|
+
timestamp: startedTs,
|
|
202
|
+
ws_root: workspaceRoot,
|
|
203
|
+
template_id: templateId || null,
|
|
204
|
+
aiws_version: aiwsVersion || null,
|
|
205
|
+
spec_version: specVersion || null,
|
|
206
|
+
started_at: startedAt,
|
|
207
|
+
finished_at: nowIsoUtc(),
|
|
208
|
+
status,
|
|
209
|
+
exit_code: status === "ok" ? 0 : exitCode || 1,
|
|
210
|
+
error: err,
|
|
211
|
+
note: "aiws validate stamp; does not include full stdout/stderr; do not put secrets in validation output.",
|
|
212
|
+
};
|
|
213
|
+
await writeText(stampPath, JSON.stringify(stamp, null, 2) + "\n");
|
|
214
|
+
console.log(`stamp: ${path.relative(workspaceRoot, stampPath)}`);
|
|
215
|
+
}
|
|
216
|
+
catch (e) {
|
|
217
|
+
console.error(`warn: failed to write validate stamp: ${e instanceof Error ? e.message : String(e)}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { UserError } from "../errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* aiws commit — validate + commit
|
|
6
|
+
* @param {{ cwd?: string, message?: string }} opts
|
|
7
|
+
*/
|
|
8
|
+
export async function wsCommitCommand({ cwd = ".", message } = {}) {
|
|
9
|
+
checkClean(cwd);
|
|
10
|
+
// Check review artifacts
|
|
11
|
+
const reviewsExist = existsSync(`${cwd}/.aiws/changes/*/review/spec-review.md`) ||
|
|
12
|
+
existsSync(`${cwd}/.aiws/changes/*/review/quality-review.md`);
|
|
13
|
+
if (!reviewsExist) {
|
|
14
|
+
console.log("warn: no spec-review or quality-review found");
|
|
15
|
+
}
|
|
16
|
+
// Run validate
|
|
17
|
+
try {
|
|
18
|
+
execSync("npx -y @aipper/aiws validate . 2>/dev/null || aiws validate . 2>/dev/null || true", { cwd, stdio: "inherit" });
|
|
19
|
+
}
|
|
20
|
+
catch { /* validate is advisory, not blocking */ }
|
|
21
|
+
// Get staged changes
|
|
22
|
+
const staged = execSync("git diff --cached --name-only", { cwd, encoding: "utf8" }).trim();
|
|
23
|
+
if (!staged) {
|
|
24
|
+
console.log("info: nothing staged. Use git add first.");
|
|
25
|
+
}
|
|
26
|
+
// Commit
|
|
27
|
+
if (!message) {
|
|
28
|
+
throw new UserError("commit requires --message (use -m or --message)", { exitCode: 2 });
|
|
29
|
+
}
|
|
30
|
+
execSync(`git commit -m "${message.replace(/"/g, '\\"')}"`, { cwd, stdio: "inherit" });
|
|
31
|
+
console.log("ok: commit created");
|
|
32
|
+
}
|
|
33
|
+
function checkClean(cwd) {
|
|
34
|
+
const out = execSync("git status --porcelain", { cwd, encoding: "utf8" }).trim();
|
|
35
|
+
if (!out) {
|
|
36
|
+
throw new UserError("Nothing to commit. Working tree clean.", { exitCode: 2 });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=ws-commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-commit.js","sourceRoot":"","sources":["../../src/commands/ws-commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,OAAO,KAAK,EAAS;IACtE,UAAU,CAAC,GAAG,CAAC,CAAC;IAEhB,yBAAyB;IACzB,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,GAAG,wCAAwC,CAAC;QAC7E,UAAU,CAAC,GAAG,GAAG,2CAA2C,CAAC,CAAC;IAChE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC9D,CAAC;IAED,eAAe;IACf,IAAI,CAAC;QACH,QAAQ,CAAC,mFAAmF,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3H,CAAC;IAAC,MAAM,CAAC,CAAC,wCAAwC,CAAC,CAAC;IAEpD,qBAAqB;IACrB,MAAM,MAAM,GAAG,QAAQ,CAAC,+BAA+B,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3F,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;IAED,SAAS;IACT,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,SAAS,CAAC,iDAAiD,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,QAAQ,CAAC,kBAAkB,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,UAAU,CAAC,GAAQ;IAC1B,MAAM,GAAG,GAAG,QAAQ,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACjF,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,SAAS,CAAC,wCAAwC,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { UserError } from "../errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* aiws deliver — submodule + superproject commit, then finish
|
|
6
|
+
* @param {{ cwd?: string, message?: string, changeId?: string }} opts
|
|
7
|
+
*/
|
|
8
|
+
export async function wsDeliverCommand({ cwd = ".", message, changeId } = {}) {
|
|
9
|
+
if (!changeId) {
|
|
10
|
+
changeId = detectChangeBranch(cwd);
|
|
11
|
+
}
|
|
12
|
+
if (!changeId) {
|
|
13
|
+
throw new UserError("Could not detect change ID.", { exitCode: 2 });
|
|
14
|
+
}
|
|
15
|
+
if (!message) {
|
|
16
|
+
throw new UserError("deliver requires --message for the superproject commit", { exitCode: 2 });
|
|
17
|
+
}
|
|
18
|
+
console.log("info: starting delivery...");
|
|
19
|
+
// Commit submodules first
|
|
20
|
+
if (existsSync(`${cwd}/.gitmodules`)) {
|
|
21
|
+
const out = execSync("git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$'", {
|
|
22
|
+
cwd, encoding: "utf8",
|
|
23
|
+
}).trim();
|
|
24
|
+
for (const line of out.split("\n")) {
|
|
25
|
+
const parts = line.trim().split(/\s+/);
|
|
26
|
+
if (parts.length < 2)
|
|
27
|
+
continue;
|
|
28
|
+
const subPath = parts[1];
|
|
29
|
+
const status = execSync(`git -C "${subPath}" status --porcelain`, { cwd, encoding: "utf8" }).trim();
|
|
30
|
+
if (status) {
|
|
31
|
+
console.log(`info: submodule ${subPath} has changes. Committing...`);
|
|
32
|
+
execSync(`git -C "${subPath}" add -A`, { cwd, stdio: "inherit" });
|
|
33
|
+
execSync(`git -C "${subPath}" commit -m "${message}"`, { cwd, stdio: "inherit" });
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.log(`info: submodule ${subPath} has no changes, skipping`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Commit superproject
|
|
41
|
+
const superStatus = execSync("git status --porcelain", { cwd, encoding: "utf8" }).trim();
|
|
42
|
+
if (superStatus) {
|
|
43
|
+
console.log("info: committing superproject...");
|
|
44
|
+
execSync("git add -A", { cwd, stdio: "inherit" });
|
|
45
|
+
execSync(`git commit -m "${message}"`, { cwd, stdio: "inherit" });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.log("info: superproject has no changes");
|
|
49
|
+
}
|
|
50
|
+
// Finish
|
|
51
|
+
await import("./ws-finish.js").then((m) => m.wsFinishCommand({ cwd, changeId, push: true }));
|
|
52
|
+
console.log("ok: deliver complete");
|
|
53
|
+
}
|
|
54
|
+
function detectChangeBranch(cwd) {
|
|
55
|
+
const branch = execSync("git branch --show-current", { cwd, encoding: "utf8" }).trim();
|
|
56
|
+
const match = branch.match(/^(?:change|changes|ws|ws-change)\/(.+)$/);
|
|
57
|
+
return match ? match[1] : null;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=ws-deliver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-deliver.js","sourceRoot":"","sources":["../../src/commands/ws-deliver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAgB,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,OAAO,EAAE,QAAQ,KAAK,EAAS;IACjF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,SAAS,CAAC,6BAA6B,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,SAAS,CAAC,wDAAwD,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAE1C,0BAA0B;IAC1B,IAAI,UAAU,CAAC,GAAG,GAAG,cAAc,CAAC,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,sEAAsE,EAAE;YAC3F,GAAG,EAAE,QAAQ,EAAE,MAAM;SACtB,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAEzB,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,OAAO,sBAAsB,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACpG,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,mBAAmB,OAAO,6BAA6B,CAAC,CAAC;gBACrE,QAAQ,CAAC,WAAW,OAAO,UAAU,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;gBAClE,QAAQ,CAAC,WAAW,OAAO,gBAAgB,OAAO,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YACpF,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,mBAAmB,OAAO,2BAA2B,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,MAAM,WAAW,GAAG,QAAQ,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzF,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,QAAQ,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAClD,QAAQ,CAAC,kBAAkB,OAAO,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACnD,CAAC;IAED,SAAS;IACT,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAC7C,CAAC,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAS,CAAC,CACxD,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAQ;IAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,2BAA2B,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACtE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC"}
|