ai-collab-open-system 0.1.0
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/.aict/START_HERE.md +127 -0
- package/.aict/WORKSPACE_MANIFEST.json +91 -0
- package/.aict/acceptance/EXAMPLE.synthetic.md +49 -0
- package/.aict/acceptance/FAILURE_MODES.md +40 -0
- package/.aict/acceptance/PROMPT.md +47 -0
- package/.aict/acceptance/README.md +44 -0
- package/.aict/acceptance/TEMPLATE.md +57 -0
- package/.aict/adapters/SHARED_CORE_CONTRACT.md +106 -0
- package/.aict/adapters/claude-code/ADAPTER.md +28 -0
- package/.aict/adapters/cline/ADAPTER.md +28 -0
- package/.aict/adapters/codex/ADAPTER.md +28 -0
- package/.aict/adapters/copilot/ADAPTER.md +28 -0
- package/.aict/adapters/cursor/ADAPTER.md +28 -0
- package/.aict/adapters/windsurf/ADAPTER.md +28 -0
- package/.aict/context/EXAMPLE.synthetic.md +53 -0
- package/.aict/context/FAILURE_MODES.md +40 -0
- package/.aict/context/PROMPT.md +47 -0
- package/.aict/context/README.md +44 -0
- package/.aict/context/TEMPLATE.md +63 -0
- package/.aict/cookbook/README.md +8 -0
- package/.aict/cookbook/bridge-to-a-second-family.md +103 -0
- package/.aict/cookbook/connect-a-tool.md +67 -0
- package/.aict/cookbook/review-a-half-product.md +79 -0
- package/.aict/cookbook/run-a-first-loop.md +81 -0
- package/.aict/examples/README.md +21 -0
- package/.aict/examples/ai-coding-long-task/CASE.md +161 -0
- package/.aict/examples/ai-coding-long-task/artifacts/acceptance-card.md +36 -0
- package/.aict/examples/ai-coding-long-task/artifacts/context-package.md +30 -0
- package/.aict/examples/ai-coding-long-task/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/ai-coding-long-task/artifacts/first-ai-output.md +109 -0
- package/.aict/examples/ai-coding-long-task/artifacts/guard-review.md +40 -0
- package/.aict/examples/ai-coding-long-task/artifacts/handoff-note.md +28 -0
- package/.aict/examples/ai-coding-long-task/artifacts/harvest-seed.md +28 -0
- package/.aict/examples/ai-coding-long-task/artifacts/revised-output.md +62 -0
- package/.aict/examples/content-production-harvest/CASE.md +87 -0
- package/.aict/examples/content-production-harvest/artifacts/acceptance-card.md +28 -0
- package/.aict/examples/content-production-harvest/artifacts/context-package.md +28 -0
- package/.aict/examples/content-production-harvest/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/content-production-harvest/artifacts/guard-review.md +28 -0
- package/.aict/examples/content-production-harvest/artifacts/handoff-note.md +28 -0
- package/.aict/examples/content-production-harvest/artifacts/harvest-seed.md +28 -0
- package/.aict/examples/multi-tool-collaboration/CASE.md +87 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/acceptance-card.md +28 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/context-package.md +28 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/guard-review.md +28 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/handoff-note.md +28 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/harvest-seed.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/CASE.md +87 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/acceptance-card.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/context-package.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/guard-review.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/handoff-note.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/harvest-seed.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/CASE.md +87 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/acceptance-card.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/context-package.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/guard-review.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/handoff-note.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/harvest-seed.md +28 -0
- package/.aict/guard/EXAMPLE.synthetic.md +51 -0
- package/.aict/guard/FAILURE_MODES.md +40 -0
- package/.aict/guard/PROMPT.md +47 -0
- package/.aict/guard/README.md +44 -0
- package/.aict/guard/TEMPLATE.md +60 -0
- package/.aict/handoff/EXAMPLE.synthetic.md +51 -0
- package/.aict/handoff/FAILURE_MODES.md +40 -0
- package/.aict/handoff/PROMPT.md +47 -0
- package/.aict/handoff/README.md +44 -0
- package/.aict/handoff/TEMPLATE.md +60 -0
- package/.aict/harvest/EXAMPLE.synthetic.md +51 -0
- package/.aict/harvest/FAILURE_MODES.md +40 -0
- package/.aict/harvest/PROMPT.md +47 -0
- package/.aict/harvest/README.md +44 -0
- package/.aict/harvest/TEMPLATE.md +60 -0
- package/.aict/mechanisms/README.md +34 -0
- package/.aict/mechanisms/anti-drift-partner/EXAMPLE.synthetic.md +46 -0
- package/.aict/mechanisms/anti-drift-partner/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/anti-drift-partner/PROMPT.md +75 -0
- package/.aict/mechanisms/anti-drift-partner/README.md +82 -0
- package/.aict/mechanisms/anti-drift-partner/TEMPLATE.md +74 -0
- package/.aict/mechanisms/blind-spot-scan/EXAMPLE.synthetic.md +39 -0
- package/.aict/mechanisms/blind-spot-scan/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/blind-spot-scan/PROMPT.md +72 -0
- package/.aict/mechanisms/blind-spot-scan/README.md +79 -0
- package/.aict/mechanisms/blind-spot-scan/TEMPLATE.md +70 -0
- package/.aict/mechanisms/collaboration-coach/EXAMPLE.synthetic.md +40 -0
- package/.aict/mechanisms/collaboration-coach/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/collaboration-coach/PROMPT.md +72 -0
- package/.aict/mechanisms/collaboration-coach/README.md +79 -0
- package/.aict/mechanisms/collaboration-coach/TEMPLATE.md +61 -0
- package/.aict/mechanisms/do-not-handle-yet/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/do-not-handle-yet/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/do-not-handle-yet/PROMPT.md +41 -0
- package/.aict/mechanisms/do-not-handle-yet/README.md +30 -0
- package/.aict/mechanisms/do-not-handle-yet/TEMPLATE.md +38 -0
- package/.aict/mechanisms/dual-guard/EXAMPLE.synthetic.md +54 -0
- package/.aict/mechanisms/dual-guard/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/dual-guard/PROMPT.md +76 -0
- package/.aict/mechanisms/dual-guard/README.md +81 -0
- package/.aict/mechanisms/dual-guard/TEMPLATE.md +73 -0
- package/.aict/mechanisms/feedback-absorption-ledger/EXAMPLE.synthetic.md +49 -0
- package/.aict/mechanisms/feedback-absorption-ledger/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/feedback-absorption-ledger/PROMPT.md +74 -0
- package/.aict/mechanisms/feedback-absorption-ledger/README.md +81 -0
- package/.aict/mechanisms/feedback-absorption-ledger/TEMPLATE.md +69 -0
- package/.aict/mechanisms/half-product-review/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/half-product-review/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/half-product-review/PROMPT.md +41 -0
- package/.aict/mechanisms/half-product-review/README.md +30 -0
- package/.aict/mechanisms/half-product-review/TEMPLATE.md +38 -0
- package/.aict/mechanisms/handoff-abc/EXAMPLE.synthetic.md +47 -0
- package/.aict/mechanisms/handoff-abc/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/handoff-abc/PROMPT.md +75 -0
- package/.aict/mechanisms/handoff-abc/README.md +82 -0
- package/.aict/mechanisms/handoff-abc/TEMPLATE.md +60 -0
- package/.aict/mechanisms/harvest-and-erc/EXAMPLE.synthetic.md +43 -0
- package/.aict/mechanisms/harvest-and-erc/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/harvest-and-erc/PROMPT.md +74 -0
- package/.aict/mechanisms/harvest-and-erc/README.md +81 -0
- package/.aict/mechanisms/harvest-and-erc/TEMPLATE.md +60 -0
- package/.aict/mechanisms/honest-calibration/EXAMPLE.synthetic.md +43 -0
- package/.aict/mechanisms/honest-calibration/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/honest-calibration/PROMPT.md +74 -0
- package/.aict/mechanisms/honest-calibration/README.md +81 -0
- package/.aict/mechanisms/honest-calibration/TEMPLATE.md +66 -0
- package/.aict/mechanisms/one-click-dispatch/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/one-click-dispatch/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/one-click-dispatch/PROMPT.md +41 -0
- package/.aict/mechanisms/one-click-dispatch/README.md +30 -0
- package/.aict/mechanisms/one-click-dispatch/TEMPLATE.md +38 -0
- package/.aict/mechanisms/plain-language-first-screen/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/plain-language-first-screen/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/plain-language-first-screen/PROMPT.md +41 -0
- package/.aict/mechanisms/plain-language-first-screen/README.md +30 -0
- package/.aict/mechanisms/plain-language-first-screen/TEMPLATE.md +38 -0
- package/.aict/mechanisms/root-cause-brake/EXAMPLE.synthetic.md +55 -0
- package/.aict/mechanisms/root-cause-brake/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/root-cause-brake/PROMPT.md +73 -0
- package/.aict/mechanisms/root-cause-brake/README.md +79 -0
- package/.aict/mechanisms/root-cause-brake/TEMPLATE.md +74 -0
- package/.aict/mechanisms/scout-review-controller/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/scout-review-controller/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/scout-review-controller/PROMPT.md +41 -0
- package/.aict/mechanisms/scout-review-controller/README.md +30 -0
- package/.aict/mechanisms/scout-review-controller/TEMPLATE.md +38 -0
- package/.aict/mechanisms/single-tool-guard/EXAMPLE.synthetic.md +54 -0
- package/.aict/mechanisms/single-tool-guard/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/single-tool-guard/PROMPT.md +76 -0
- package/.aict/mechanisms/single-tool-guard/README.md +83 -0
- package/.aict/mechanisms/single-tool-guard/TEMPLATE.md +75 -0
- package/.aict/mechanisms/task-splitting/EXAMPLE.synthetic.md +53 -0
- package/.aict/mechanisms/task-splitting/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/task-splitting/PROMPT.md +72 -0
- package/.aict/mechanisms/task-splitting/README.md +79 -0
- package/.aict/mechanisms/task-splitting/TEMPLATE.md +76 -0
- package/.aict/modes/README.md +11 -0
- package/.aict/modes/execute.md +31 -0
- package/.aict/modes/handoff.md +29 -0
- package/.aict/modes/harvest.md +30 -0
- package/.aict/modes/review.md +28 -0
- package/.aict/modes/shape.md +34 -0
- package/.aict/privacy/COMMERCIAL_BOUNDARY.md +34 -0
- package/.aict/privacy/PRIVACY.md +36 -0
- package/.aict/privacy/REDACTION_CHECKLIST.md +12 -0
- package/.aict/profile/CANDIDATES.md +44 -0
- package/.aict/profile/EXAMPLE.synthetic.md +49 -0
- package/.aict/profile/FAILURE_MODES.md +40 -0
- package/.aict/profile/PROMPT.md +47 -0
- package/.aict/profile/README.md +44 -0
- package/.aict/profile/TEMPLATE.md +57 -0
- package/.aict/prompts/acceptance-definition.md +109 -0
- package/.aict/prompts/guard-review.md +116 -0
- package/.aict/prompts/handoff-generation.md +110 -0
- package/.aict/prompts/harvest-extraction.md +110 -0
- package/.aict/prompts/mode-switching.md +66 -0
- package/.aict/prompts/profile-creation.md +66 -0
- package/.aict/prompts/profile-refinement.md +66 -0
- package/.aict/prompts/project-context-packaging.md +113 -0
- package/.aict/prompts/red-team-challenge.md +106 -0
- package/.aict/prompts/rule-update-proposal.md +114 -0
- package/.aict/prompts/workflow-reset.md +109 -0
- package/.aict/roles/README.md +18 -0
- package/.aict/roles/executor.md +34 -0
- package/.aict/roles/harvester.md +33 -0
- package/.aict/roles/owner-controller.md +38 -0
- package/.aict/roles/scout.md +33 -0
- package/.aict/roles/supervisor.md +34 -0
- package/.aict/roles/system-guardian.md +34 -0
- package/.aict/skills/acceptance/SKILL.md +43 -0
- package/.aict/skills/context/SKILL.md +44 -0
- package/.aict/skills/evidence-pack/SKILL.md +42 -0
- package/.aict/skills/guard/SKILL.md +46 -0
- package/.aict/skills/handoff/SKILL.md +44 -0
- package/.aict/skills/harvest/SKILL.md +44 -0
- package/.aict/skills/mode-switch/SKILL.md +42 -0
- package/.aict/skills/profile/SKILL.md +42 -0
- package/.aict/skills/red-team/SKILL.md +42 -0
- package/.aict/skills/single-tool-guard/SKILL.md +42 -0
- package/.aict/state/CURRENT_STATE.md +13 -0
- package/.aict/state/DECISIONS.md +7 -0
- package/.aict/state/TASK_LOG.md +7 -0
- package/.aict/state/evidence.jsonl +2 -0
- package/.aict/state/learning-ledger.jsonl +1 -0
- package/.aict/state/receipts.jsonl +1 -0
- package/.aict/state/runs.jsonl +1 -0
- package/.aict/state/tasks.jsonl +1 -0
- package/.aict/walkthroughs/10-minute-your-task.md +107 -0
- package/.aict/walkthroughs/10-minute.md +43 -0
- package/.aict/walkthroughs/30-minute.md +22 -0
- package/.aict/walkthroughs/60-minute.md +27 -0
- package/.aict/walkthroughs/synthetic-loop-transcript.md +43 -0
- package/CHANGELOG.md +23 -0
- package/CODE_OF_CONDUCT.md +20 -0
- package/CONTRIBUTING.md +30 -0
- package/KNOWN_LIMITATIONS.md +54 -0
- package/LICENSE +199 -0
- package/PRODUCT_CONTRACT.md +446 -0
- package/README.md +245 -0
- package/RELEASE_CHECKLIST.md +78 -0
- package/SECURITY.md +56 -0
- package/START_HERE.md +89 -0
- package/bin/ai-collab.js +2 -0
- package/docs/DOGFOOD.md +85 -0
- package/docs/FEEDBACK.md +61 -0
- package/docs/FIRST_EXPERIENCE_SPEC.md +32 -0
- package/docs/FREE_VS_PAID.md +53 -0
- package/docs/PUBLIC_BOUNDARY.md +36 -0
- package/docs/PUBLIC_MAPPING.md +178 -0
- package/docs/RELEASE_PRIORITY.md +23 -0
- package/docs/WHY_THIS_EXISTS.md +36 -0
- package/docs/open-system/00-start-here.md +60 -0
- package/docs/open-system/01-ai-collaboration-os.md +33 -0
- package/docs/open-system/02-six-layer-architecture.md +45 -0
- package/docs/open-system/03-role-system.md +33 -0
- package/docs/open-system/04-core-mechanisms.md +34 -0
- package/docs/open-system/05-failure-patterns.md +31 -0
- package/docs/open-system/06-how-to-adapt-to-your-workflow.md +31 -0
- package/package.json +69 -0
- package/privacy-manifest.json +78 -0
- package/privacy-scan.local.json.example +18 -0
- package/scripts/lib/forbidden-in-pack.js +55 -0
- package/scripts/pack-check.js +154 -0
- package/scripts/privacy-scan.js +487 -0
- package/scripts/validate-contract.js +160 -0
- package/src/adapters.js +590 -0
- package/src/bootstrap.js +1184 -0
- package/src/catalog.js +2723 -0
- package/src/cli.js +2899 -0
- package/src/dialogue.js +470 -0
- package/src/i18n.js +1034 -0
- package/src/ledger.js +2011 -0
- package/src/render.js +1381 -0
- package/src/sendmodel.js +452 -0
- package/src/validate.js +1307 -0
- package/src/workspace.js +1679 -0
- package/tests/contract.test.js +8514 -0
package/src/i18n.js
ADDED
|
@@ -0,0 +1,1034 @@
|
|
|
1
|
+
// === i18n (bilingual EN/ZH, honesty-faithful) ===============================
|
|
2
|
+
//
|
|
3
|
+
// This module makes the CLI speak the user's language WITHOUT softening a single
|
|
4
|
+
// honesty marker. English is the CANONICAL source of truth: every key has an `en`
|
|
5
|
+
// value (the exact wording the CLI shipped with), and the Chinese (`zh`) value is a
|
|
6
|
+
// FAITHFUL, NON-SOFTENED translation. Where a string carries a trust caveat
|
|
7
|
+
// (unverified / self-declared / proposed / pending / not signed off), the Chinese
|
|
8
|
+
// keeps that caveat verbatim — it is a red line that an "unverified" claim is never
|
|
9
|
+
// rendered as "done/verified/saved" in any language.
|
|
10
|
+
//
|
|
11
|
+
// Three pure exports:
|
|
12
|
+
// resolveLocale({ langFlag, env }) -> 'en' | 'zh' (the precedence ladder)
|
|
13
|
+
// t(key, params, locale) -> the localized string ({name} interpolated)
|
|
14
|
+
// MESSAGES -> the catalog (en canonical, zh faithful)
|
|
15
|
+
//
|
|
16
|
+
// Fallback chain in t(): zh missing -> en -> the key itself. So a not-yet-translated
|
|
17
|
+
// key degrades to English (never an empty line, never a crash), and a typo'd key
|
|
18
|
+
// surfaces as its own name rather than blank — visible, debuggable, never silent.
|
|
19
|
+
|
|
20
|
+
// --- Locale resolution ------------------------------------------------------
|
|
21
|
+
//
|
|
22
|
+
// Precedence (highest first), per the product contract:
|
|
23
|
+
// 1. an explicit --lang <en|zh> flag (the user said so on THIS run)
|
|
24
|
+
// 2. the AI_COLLAB_LANG env var (a per-shell / CI override)
|
|
25
|
+
// 3. the OS locale: LC_ALL > LC_MESSAGES > LANG (POSIX precedence); a value whose
|
|
26
|
+
// language part starts with "zh" -> 'zh'
|
|
27
|
+
// 4. default 'en' (English is the canonical fallback)
|
|
28
|
+
// Pure: it reads only its arguments (env is passed in, never process.env directly),
|
|
29
|
+
// so it is trivially testable for every branch.
|
|
30
|
+
export function resolveLocale({ langFlag, env = {} } = {}) {
|
|
31
|
+
// 1) Explicit flag wins outright. Only the two supported values are honored; any
|
|
32
|
+
// other value (a typo) falls through to the next source rather than throwing,
|
|
33
|
+
// so a mistyped --lang never hard-fails a command (it just is not applied).
|
|
34
|
+
if (langFlag === "en" || langFlag === "zh") return langFlag;
|
|
35
|
+
|
|
36
|
+
// 2) AI_COLLAB_LANG env override. Same two-value contract as the flag.
|
|
37
|
+
const envLang = typeof env.AI_COLLAB_LANG === "string" ? env.AI_COLLAB_LANG.trim().toLowerCase() : "";
|
|
38
|
+
if (envLang === "en" || envLang === "zh") return envLang;
|
|
39
|
+
|
|
40
|
+
// 3) OS locale, POSIX precedence LC_ALL > LC_MESSAGES > LANG. We look at the
|
|
41
|
+
// language part (before any "_"/"." ) and only special-case "zh" -> 'zh';
|
|
42
|
+
// everything else (and an empty/"C"/"POSIX" locale) leaves us at the default.
|
|
43
|
+
const osLocale =
|
|
44
|
+
firstNonEmpty(env.LC_ALL) ??
|
|
45
|
+
firstNonEmpty(env.LC_MESSAGES) ??
|
|
46
|
+
firstNonEmpty(env.LANG);
|
|
47
|
+
if (typeof osLocale === "string") {
|
|
48
|
+
const lang = osLocale.toLowerCase();
|
|
49
|
+
if (lang.startsWith("zh")) return "zh";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 4) Default: English (canonical).
|
|
53
|
+
return "en";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Return the trimmed string if it is a non-empty string, else undefined — so the
|
|
57
|
+
// ?? ladder in resolveLocale falls through empty env vars (LC_ALL="" must NOT win).
|
|
58
|
+
function firstNonEmpty(value) {
|
|
59
|
+
if (typeof value !== "string") return undefined;
|
|
60
|
+
const trimmed = value.trim();
|
|
61
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// --- Interpolation ----------------------------------------------------------
|
|
65
|
+
//
|
|
66
|
+
// Replace {name} placeholders with params.name. A param that is undefined/null is
|
|
67
|
+
// rendered as the empty string (so a missing param never prints the literal "{name}"
|
|
68
|
+
// nor "undefined"); a placeholder with no matching param is left intact so the gap
|
|
69
|
+
// is visible rather than silently swallowed. Pure string transform.
|
|
70
|
+
function interpolate(template, params) {
|
|
71
|
+
if (typeof template !== "string") return template;
|
|
72
|
+
if (!params || typeof params !== "object") return template;
|
|
73
|
+
return template.replace(/\{(\w+)\}/g, (whole, name) => {
|
|
74
|
+
if (Object.prototype.hasOwnProperty.call(params, name)) {
|
|
75
|
+
const value = params[name];
|
|
76
|
+
return value === undefined || value === null ? "" : String(value);
|
|
77
|
+
}
|
|
78
|
+
return whole; // unknown placeholder: leave as-is (visible, not swallowed)
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// --- t(): the lookup + fallback + interpolation -----------------------------
|
|
83
|
+
//
|
|
84
|
+
// Resolve `key` in the requested locale, falling back zh -> en -> key, then
|
|
85
|
+
// interpolate {params}. `locale` defaults to 'en' so a caller that forgets to thread
|
|
86
|
+
// it still gets the canonical English (never a crash, never an empty string).
|
|
87
|
+
export function t(key, params = {}, locale = "en") {
|
|
88
|
+
const lang = locale === "zh" ? "zh" : "en";
|
|
89
|
+
const table = MESSAGES[lang] || {};
|
|
90
|
+
let template = table[key];
|
|
91
|
+
if (template === undefined && lang !== "en") {
|
|
92
|
+
// zh miss -> English canonical.
|
|
93
|
+
template = MESSAGES.en[key];
|
|
94
|
+
}
|
|
95
|
+
if (template === undefined) {
|
|
96
|
+
// Still missing -> the key itself (visible + debuggable, never empty/blank).
|
|
97
|
+
return key;
|
|
98
|
+
}
|
|
99
|
+
return interpolate(template, params);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// --- The catalog ------------------------------------------------------------
|
|
103
|
+
//
|
|
104
|
+
// Organized by dotted key. en = canonical (verbatim from the shipped CLI so English
|
|
105
|
+
// output is byte-identical and the existing English test assertions keep passing).
|
|
106
|
+
// zh = faithful translation; honesty caveats are preserved word-for-word per the
|
|
107
|
+
// authoritative glossary, NEVER softened into "done/verified/saved".
|
|
108
|
+
export const MESSAGES = {
|
|
109
|
+
en: {
|
|
110
|
+
// ---- shared / cross-cutting ----
|
|
111
|
+
"common.networkNotUsed": "Network: not used.",
|
|
112
|
+
"common.untitled": "(untitled)",
|
|
113
|
+
|
|
114
|
+
// ---- guard-level plain language (the honesty ladder, in one clause each) ----
|
|
115
|
+
"level.L0": "summary only — not enough evidence to pass",
|
|
116
|
+
"level.L1": "evidence too thin to pass yet — add a real run/output",
|
|
117
|
+
"level.L2": "single-tool check — accept only with eyes-open risk",
|
|
118
|
+
"level.L2_5": "same tool, different model — still single-family, accept with risk",
|
|
119
|
+
"level.L3": "cross-family pass — re-checked by a different model family (self-declared)",
|
|
120
|
+
"level.L4": "strongest local pass — cross-family review plus a reconciled rerun",
|
|
121
|
+
// The self-declared marker, surfaced verbatim wherever a cross-family receipt shows.
|
|
122
|
+
"marker.selfDeclaredCrossFamily": "self-declared cross-family, unverified",
|
|
123
|
+
|
|
124
|
+
// ---- welcome (the proactive onboarding intro the CLI prints VERBATIM) ----
|
|
125
|
+
// This is HARD-PRINTED, fixed copy: the AI installs the pack, then runs `welcome`
|
|
126
|
+
// and shows the user this output as-is, so the intro is guaranteed to appear in
|
|
127
|
+
// full instead of being re-summarized (and possibly garbled) by the model. The
|
|
128
|
+
// English is the canonical source; the zh twin is the Owner-locked 4th draft.
|
|
129
|
+
// Honesty contract: the privacy line is faithful — it does NOT claim "zero data
|
|
130
|
+
// leaves your machine". The tool itself is offline and uploads nothing, but the
|
|
131
|
+
// ONE optional "let me scan your recent work" step is the AI reading your work and
|
|
132
|
+
// passing it through its provider the same as any normal chat, so we say so plainly
|
|
133
|
+
// rather than over-claiming privacy.
|
|
134
|
+
"welcome.intro":
|
|
135
|
+
"✅ Your AI collaboration pack is installed\n" +
|
|
136
|
+
"\n" +
|
|
137
|
+
"You just gave your AI tool (Claude Code / Cursor / Codex, etc.) a local collaboration\n" +
|
|
138
|
+
"framework — think of it as scaffolding for the AI, so it works more reliably, gets to\n" +
|
|
139
|
+
"know you, and does not start from scratch every time.\n" +
|
|
140
|
+
"The tool itself does not go online and uploads nothing; your material stays on your\n" +
|
|
141
|
+
"machine. The one exception is when you ask me to \"take a look at your work\": that one\n" +
|
|
142
|
+
"step is me, the AI, reading it and passing it through my provider the same way our\n" +
|
|
143
|
+
"normal chat already does — the tool itself sends nothing.\n" +
|
|
144
|
+
"\n" +
|
|
145
|
+
"[Six layers of ability added to your AI]\n" +
|
|
146
|
+
" Profile Builds a local profile of you that gets to know you the more you use it.\n" +
|
|
147
|
+
" Context Gives every task its own file, so work carries across conversations.\n" +
|
|
148
|
+
" Acceptance Pins down \"what counts as done\" before any work starts, so the AI does not drift.\n" +
|
|
149
|
+
" Guard Demands evidence before saying \"done\", and can pull in a second AI to re-check.\n" +
|
|
150
|
+
" Handoff Switch tools or conversations without re-explaining the background.\n" +
|
|
151
|
+
" Harvest Captures the lessons worth keeping, so you can reuse them next time.\n" +
|
|
152
|
+
"\n" +
|
|
153
|
+
"[What you will actually notice change]\n" +
|
|
154
|
+
" · The AI no longer just says \"done\" when it is not — it has to prove it with evidence.\n" +
|
|
155
|
+
" · Important decisions get a dual-guard re-check; it is not one AI's word alone.\n" +
|
|
156
|
+
" · Switch conversations or tools, and the background is not lost.\n" +
|
|
157
|
+
" · When you are stuck, it helps you untangle your thinking.\n" +
|
|
158
|
+
"\n" +
|
|
159
|
+
"[Stuck on something? Just say the keyword and the AI switches to the matching mode]\n" +
|
|
160
|
+
" Say \"collision mode\" → the AI argues your view and pokes at logic holes, to make a fuzzy idea clear\n" +
|
|
161
|
+
" Say \"scan blind spots\" → the AI takes an outside view to find the dead angles you cannot see\n" +
|
|
162
|
+
" Say \"red team\" → the AI deliberately attacks the weaknesses in your plan\n" +
|
|
163
|
+
" (There is also dual-guard re-check, root-cause analysis, and more — just ask when you need them)\n" +
|
|
164
|
+
"\n" +
|
|
165
|
+
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +
|
|
166
|
+
"Before you dive into work — take 30 seconds and let me show you, first-hand, what it can do for you.\n" +
|
|
167
|
+
"I will take a look at your recent work right now and point out, on the spot:\n" +
|
|
168
|
+
" · Which tasks you thought were \"done\" actually left no verification evidence (the easiest trap to fall into)\n" +
|
|
169
|
+
" · The high-risk tasks you recently touched, and which helper roles (red team / dual guard) should vet them\n" +
|
|
170
|
+
" · A working-habits profile read from your actual work (you confirm or correct it — no form to fill in)\n" +
|
|
171
|
+
" · The lessons from this round worth saving\n" +
|
|
172
|
+
"You do not have to do anything — just reply \"go ahead\" and I will start. Try it once and you will see where it earns its keep. Want me to take a look right now?",
|
|
173
|
+
|
|
174
|
+
// ---- init (writing) ----
|
|
175
|
+
"init.created.title": "AI Collaboration Open System workspace created.",
|
|
176
|
+
"init.created.body":
|
|
177
|
+
"Workspace: {workspaceRoot}\n" +
|
|
178
|
+
"START_HERE.md: {startHere}\n" +
|
|
179
|
+
"Files written: {files}\n" +
|
|
180
|
+
"{backupLine}{network}\n" +
|
|
181
|
+
"Why this works: AI productivity is a product, not a sum — this adds the factors beyond raw model capability (profile, context, acceptance, guard, handoff, harvest). See docs/WHY_THIS_EXISTS.md.\n" +
|
|
182
|
+
"On its first reply, your AI is instructed to offer to scan your recent work and show you what changes (whether it actually does depends on your tool loading this rule) — you do not have to run anything for that. Want a read-only baseline yourself right now? Run: node bin/ai-collab.js bootstrap --yes (a local \"AI collaboration baseline\" report — nothing is written or sent anywhere).\n" +
|
|
183
|
+
"Next: open {walkthroughYourTask} and run one full loop on your own real task (or open {walkthrough} to watch the flow on a prepared example first).",
|
|
184
|
+
"init.backupLine": "Backup: {backupPath}\n",
|
|
185
|
+
// dry-run preview
|
|
186
|
+
"init.dryRun.title": "Dry run. No files written.",
|
|
187
|
+
"init.dryRun.body":
|
|
188
|
+
"Workspace: {workspaceRoot}\n" +
|
|
189
|
+
"Files planned: {files}\n" +
|
|
190
|
+
"Existing workspace: {existing}\n" +
|
|
191
|
+
"{defaultTargetLine}{network}",
|
|
192
|
+
"init.dryRun.existing.yes": "yes",
|
|
193
|
+
"init.dryRun.existing.no": "no",
|
|
194
|
+
"init.dryRun.defaultTargetLine":
|
|
195
|
+
"Target not given; previewed the default {target}. To write, run: node bin/ai-collab.js init --target <dir>\n",
|
|
196
|
+
|
|
197
|
+
// ---- status ----
|
|
198
|
+
"status.title": "Workspace status",
|
|
199
|
+
"status.state": "State: {stateDir}",
|
|
200
|
+
"status.tasks": "Tasks: {count} [{breakdown}]{seedNote}",
|
|
201
|
+
"status.evidence": "Evidence: {count}{seedNote}",
|
|
202
|
+
"status.runs": "Runs: {count} [{breakdown}]{seedNote}",
|
|
203
|
+
"status.receipts": "Receipts: {count} [{breakdown}]{seedNote}",
|
|
204
|
+
"status.learning": "Learning candidates: {count}",
|
|
205
|
+
"status.yourTasks": "Your tasks:",
|
|
206
|
+
"status.seedNote.tasks": " (includes {count} example seed{plural} — delete it and add your own)",
|
|
207
|
+
"status.seedNote.generic": " (includes {count} example seed{plural})",
|
|
208
|
+
"status.taskLine.head": " - {id} {title} [{status}]{seedTag}",
|
|
209
|
+
"status.taskLine.seedTag": " [example seed]",
|
|
210
|
+
// The honesty-bearing task status label (a "done" with no accepted review). The
|
|
211
|
+
// ledger model emits the English canonical (a stable data field); this key is the
|
|
212
|
+
// render-time translation, faithful — "author-marked, unverified" is NOT softened.
|
|
213
|
+
"status.display.authorMarkedDone": "done — author-marked, unverified",
|
|
214
|
+
"status.taskLine.receipt": " receipt {id}: {verdict} · {level} · {status}{acceptedBy}{unverified}{plainNote}",
|
|
215
|
+
"status.taskLine.receipt.acceptedBy": " by {who}",
|
|
216
|
+
"status.taskLine.receipt.unverified": " (self-declared cross-family, unverified)",
|
|
217
|
+
"status.taskLine.receipt.plainNote": "\n ({level}: {plain})",
|
|
218
|
+
"status.taskLine.receipt.none": " receipt: (none yet)",
|
|
219
|
+
"status.taskLine.counts": " evidence: {evidence} · runs: {runs}",
|
|
220
|
+
"status.handoffLine": "Handoff drafts: {count} (latest: {latest}) — review before handing off",
|
|
221
|
+
"status.carryLine": "Carrying forward the preference you confirmed: {content}",
|
|
222
|
+
"status.harvestLine": "Most recent harvest lesson you kept: {content}",
|
|
223
|
+
"status.mostRecentActivity": "Most recent activity: {latest}",
|
|
224
|
+
"status.noActivity": "(no activity yet)",
|
|
225
|
+
"status.nextStep.withCommand": "Next step: {text}\n {command}",
|
|
226
|
+
"status.nextStep.textOnly": "Next step: {text}",
|
|
227
|
+
// status next-step messages (text + command threaded by the command builder)
|
|
228
|
+
"status.next.noOwnWork.text": "No work of your own yet — see where you stand on your recent work, or start a task.",
|
|
229
|
+
"status.next.noEvidence.text": "Task {id} has no evidence yet — run its command and record the real result.",
|
|
230
|
+
"status.next.noReceipt.text": "Task {id} has evidence but no receipt — file the guard verdict.",
|
|
231
|
+
"status.next.pending.text": "Receipt {receiptId} on task {taskId} is pending your sign-off — accept it (or add a cross-family review to reach L3).",
|
|
232
|
+
"status.next.missingHandoff.text": "Your work is recorded but there is no handoff draft — generate one so the next session/tool can resume.",
|
|
233
|
+
"status.next.keepLesson.text": "You have a proposed lesson ({id}) — keep it so it carries forward.",
|
|
234
|
+
"status.next.allClear.text": "All your tasks are evidenced, signed off, and handed off — nothing outstanding. Start a new task when ready.",
|
|
235
|
+
|
|
236
|
+
// ---- bootstrap report ----
|
|
237
|
+
"bootstrap.report.title": "Your AI collaboration baseline (from your own recent work)",
|
|
238
|
+
"bootstrap.report.scanned": "Scanned locally: {repoRoot}",
|
|
239
|
+
"bootstrap.report.readonly": "Read-only. Nothing left this machine.",
|
|
240
|
+
// empty / seed-only honesty block
|
|
241
|
+
"bootstrap.empty.line1": "You don’t have any of your own work recorded yet — only the shipped example.",
|
|
242
|
+
"bootstrap.empty.line2": "So there is nothing of yours to report on. To get a real baseline:",
|
|
243
|
+
"bootstrap.empty.step1": " 1. Run one real task through the loop (see `guide`).",
|
|
244
|
+
"bootstrap.empty.step2": " 2. Re-run `bootstrap` and it will report on YOUR work.",
|
|
245
|
+
"bootstrap.empty.note": "(The example seed is intentionally excluded — it is not your result.)",
|
|
246
|
+
// PROFILE card (DETERMINISTIC clues only — NO semantic verdict). Every line is a
|
|
247
|
+
// fact from the local scan; the footer states the honesty contract: these are
|
|
248
|
+
// clues for the user's OWN ai to confirm, not a conclusion bootstrap reached.
|
|
249
|
+
"bootstrap.profile.title": "PROFILE CLUES — signals from your setup (not conclusions)",
|
|
250
|
+
"bootstrap.profile.tools": " Detected you using: {tools}.",
|
|
251
|
+
"bootstrap.profile.multiTool": " (more than one tool configured — a cross-tool collaboration signal.)",
|
|
252
|
+
"bootstrap.profile.noTools": " No AI instruction files detected here yet.",
|
|
253
|
+
"bootstrap.profile.fileTypes": " Recently changed file types: {names}.",
|
|
254
|
+
"bootstrap.profile.testScript": " Your package.json has a test script.",
|
|
255
|
+
"bootstrap.profile.footer": " These are clues, not conclusions. Your AI will use them to confirm your full working-habits profile with you.",
|
|
256
|
+
// ROLES card (DETERMINISTIC keyword match -> existing role packages). It states a
|
|
257
|
+
// FACT (a high-risk WORD appears) + a fixed mapping to a role; it never decides the
|
|
258
|
+
// work IS risky — the user's ai does. Role labels carry a plain-language simile.
|
|
259
|
+
"bootstrap.roles.title": "ROLES TO CONSIDER — from high-risk keywords in your work",
|
|
260
|
+
"bootstrap.roles.none": " No high-risk keywords matched in your recent work. (A keyword scan only — not a verdict that the work is low-risk; ask your AI if a task still needs a guard role.)",
|
|
261
|
+
"bootstrap.roles.intro": " {count} high-risk signal{plural} found (keyword matches — your AI confirms whether they truly apply):",
|
|
262
|
+
"bootstrap.roles.item": " - “{subject}” contains the keyword “{keyword}” → consider {roles}.",
|
|
263
|
+
"bootstrap.roles.roleJoin": " + ",
|
|
264
|
+
"bootstrap.roles.role.red-team": "red-team (someone whose whole job is to poke holes)",
|
|
265
|
+
"bootstrap.roles.role.dual-guard": "dual-guard (a second, different AI double-checks it)",
|
|
266
|
+
"bootstrap.roles.role.scout-review-controller": "scout-review-controller (SCOUT — gathers the outside facts first)",
|
|
267
|
+
// VERIFY card
|
|
268
|
+
"bootstrap.verify.title": "VERIFY — which “done” you can’t trust yet",
|
|
269
|
+
"bootstrap.verify.allClear1": " Nothing is over-claimed right now. No completion is being shown as done",
|
|
270
|
+
"bootstrap.verify.allClear2": " without the evidence to back it.",
|
|
271
|
+
"bootstrap.verify.count": " {count} completion claim{plural} cannot be trusted as done yet:",
|
|
272
|
+
"bootstrap.verify.item": " - {taskId} “{title}”: {reason}",
|
|
273
|
+
"bootstrap.verify.detail": " detail: receipt {id} = {verdict} · {level} · {status}{marker}",
|
|
274
|
+
// VERIFY reason codes
|
|
275
|
+
"bootstrap.verify.reason.pending_receipt": "a review exists but is still pending — not accepted",
|
|
276
|
+
"bootstrap.verify.reason.pass_with_risk_unaccepted": "passed only with a noted risk that no one has signed off on yet",
|
|
277
|
+
"bootstrap.verify.reason.self_declared_cross_family": "self-declared cross-family review — the tool cannot verify the other model actually checked it",
|
|
278
|
+
"bootstrap.verify.reason.author_marked_done": "marked done by the author with no accepted review behind it",
|
|
279
|
+
// RESUME card
|
|
280
|
+
"bootstrap.resume.title": "RESUME — where you are, what’s missing",
|
|
281
|
+
"bootstrap.resume.noActive": " No open or in-progress tasks of your own right now.",
|
|
282
|
+
"bootstrap.resume.count": " {count} task{plural} still in progress:",
|
|
283
|
+
"bootstrap.resume.item": " - {id} “{title}” [{status}]",
|
|
284
|
+
"bootstrap.resume.missingHandoff": " No handoff note yet — the next session would start from zero. Run `handoff create`.",
|
|
285
|
+
"bootstrap.resume.reTouch": " You keep re-touching the same files across recent commits: {names}.",
|
|
286
|
+
"bootstrap.resume.reTouchNote": " (a possible “said done, still patching” signal — worth a closer look.)",
|
|
287
|
+
"bootstrap.resume.uncommitted": " You have uncommitted changes in flight.",
|
|
288
|
+
// HARVEST card
|
|
289
|
+
"bootstrap.harvest.title": "HARVEST — what you can carry forward",
|
|
290
|
+
"bootstrap.harvest.none1": " Nothing confirmed to carry forward yet. Confirm a lesson with `learning confirm`",
|
|
291
|
+
"bootstrap.harvest.none2": " and it will show up here.",
|
|
292
|
+
"bootstrap.harvest.candidate": " - {detail} (proposed — nothing is saved automatically).",
|
|
293
|
+
"bootstrap.harvest.confirmedHead": " Confirmed learnings:",
|
|
294
|
+
"bootstrap.harvest.confirmedItem": " - ({type}) {content}",
|
|
295
|
+
// HARVEST candidate details
|
|
296
|
+
"bootstrap.harvest.detail.confirmed_learnings_ready": "{count} confirmed learning{plural} you can carry into your next task",
|
|
297
|
+
"bootstrap.harvest.detail.verified_done_tasks": "{count} task{plural} reached a verified (accepted) result — a pattern worth reusing",
|
|
298
|
+
// bootstrap Next step lines
|
|
299
|
+
"bootstrap.next.pending.text": "Next: receipt {receiptId} (task {taskId}) is pending — accept it after you’ve checked it, or raise it with a cross-family review.",
|
|
300
|
+
"bootstrap.next.pending.cmd": " node bin/ai-collab.js receipt accept --id {receiptId} --owner you",
|
|
301
|
+
"bootstrap.next.selfCross.text": "Next: receipt {receiptId} on task {taskId} is a self-declared cross-family pass the tool can’t verify — re-run it yourself to back it with a recorded run.",
|
|
302
|
+
"bootstrap.next.selfCross.cmd": " node bin/ai-collab.js run exec --task {taskId} --command \"...\"",
|
|
303
|
+
"bootstrap.next.authorDone.text": "Next: task {taskId} is marked done with no accepted review — add evidence and file a receipt so it is actually backed.",
|
|
304
|
+
"bootstrap.next.authorDone.cmd": " node bin/ai-collab.js receipt create --task {taskId} --verdict pass_with_risk --review-mode self --evidence <id>",
|
|
305
|
+
"bootstrap.next.missingHandoff.text": "Next: generate a handoff draft so the next session/tool resumes without re-explaining.",
|
|
306
|
+
"bootstrap.next.missingHandoff.cmd": " node bin/ai-collab.js handoff create",
|
|
307
|
+
"bootstrap.next.keepLesson.text": "Next: keep the lesson you proposed ({id}) so it carries into your next task.",
|
|
308
|
+
"bootstrap.next.keepLesson.cmd": " node bin/ai-collab.js learning confirm --id {id}",
|
|
309
|
+
"bootstrap.next.allClear.text": "Next: keep running real tasks through the loop; re-run `bootstrap` anytime for an updated baseline.",
|
|
310
|
+
// Roles hint, APPENDED after the primary next step when high-risk keywords matched
|
|
311
|
+
// (it never replaces the verify action). Advisory: points at existing role packages.
|
|
312
|
+
"bootstrap.next.roles.text": "Also: high-risk keywords showed up in your work — consider bringing in {roles} before you call it done.",
|
|
313
|
+
// consent preview
|
|
314
|
+
"bootstrap.consent.head": "bootstrap will read — locally, read-only — to build your baseline:",
|
|
315
|
+
"bootstrap.consent.repo": " - your repo structure under {repoRoot} (file names, package.json scripts)",
|
|
316
|
+
"bootstrap.consent.git": " - your recent git history (git log / git diff --stat) in this repo",
|
|
317
|
+
"bootstrap.consent.ledger": " - your .aict ledger (tasks, runs, evidence, receipts, learnings)",
|
|
318
|
+
"bootstrap.consent.ai": " - your AI instruction files (CLAUDE.md / AGENTS.md / .cursorrules / …)",
|
|
319
|
+
"bootstrap.consent.promise": "It does NOT call any external model, makes no guess, and sends nothing anywhere.",
|
|
320
|
+
"bootstrap.consent.rerun": "Re-run with --yes to confirm and see your baseline:",
|
|
321
|
+
"bootstrap.consent.cmd": " node bin/ai-collab.js bootstrap --yes",
|
|
322
|
+
// Only shown when the user opted in by naming a dialogue/log file (the connector
|
|
323
|
+
// is OFF by default). The honesty caveat — local, deterministic, redacted — rides
|
|
324
|
+
// along so the extra high-privacy read is never silent.
|
|
325
|
+
"bootstrap.consent.dialogue": " - the local chat/log export(s) you named: {files} (read locally, redacted, deterministic — never sent anywhere)",
|
|
326
|
+
|
|
327
|
+
// --- bootstrap --send-to-model (the ONE external-model path) -------------
|
|
328
|
+
// Consent preview (shown BEFORE any send): exactly what will leave the machine.
|
|
329
|
+
"send.preview.head": "About to send to an external model — here is EXACTLY what would go out:",
|
|
330
|
+
"send.preview.model": " model: {model} (the prompt is delivered on stdin, never on the command line)",
|
|
331
|
+
"send.preview.count": " {count} redacted snippet{plural} from your local scan",
|
|
332
|
+
"send.preview.redacted": " every snippet is REDACTED (secrets / tokens / emails / local paths masked) and the whole payload is re-checked before it leaves",
|
|
333
|
+
"send.preview.sources": " from: {files}",
|
|
334
|
+
"send.preview.promise": "Nothing else (no raw files, no ledger, no repo contents) is sent. This is the only feature that contacts a model off this machine.",
|
|
335
|
+
// Confirmation (interactive TTY). Default-deny: only an explicit y/yes proceeds.
|
|
336
|
+
"send.confirm.prompt": "Send these redacted snippets to the model? [y/N] ",
|
|
337
|
+
// Non-interactive refusal (no TTY and no --yes): nothing was sent.
|
|
338
|
+
"send.refusedNonTty": "Refused: a send needs your confirmation. Re-run with --yes to confirm in a non-interactive shell. Nothing was sent.",
|
|
339
|
+
// The user declined at the prompt.
|
|
340
|
+
"send.declined": "Declined — nothing was sent. Showing your local result only.",
|
|
341
|
+
// The LLM candidate block: clearly labelled lowest-trust, proposed, unverified.
|
|
342
|
+
"send.candidates.head": "From the external model — {count} suggestion{plural} (NOT part of your verified results):",
|
|
343
|
+
"send.candidates.caveat": " ⚠ AI suggestion · low confidence · unverified · proposed only — confirm each one yourself before trusting or saving it. Nothing here was written anywhere.",
|
|
344
|
+
"send.candidates.item": " - [{kind}] {summary}",
|
|
345
|
+
"send.candidates.basis": " basis: {basis}",
|
|
346
|
+
"send.candidates.kind.false_completion": "claimed done · unverified",
|
|
347
|
+
"send.candidates.kind.profile_candidate": "possible standing preference",
|
|
348
|
+
"send.candidates.kind.context_gap": "possible missing context",
|
|
349
|
+
"send.candidates.kind.harvest_candidate": "possible reusable lesson",
|
|
350
|
+
// Graceful-degrade lines (the model was not used / not reachable).
|
|
351
|
+
"send.degraded.no_redacted_snippets": "No external send: there were no redacted snippets to send (provide a chat/log export with --dialogue/--logs first). Your local result above stands.",
|
|
352
|
+
"send.degraded.consent_required_non_tty": "No external send: confirmation was required and not given (--yes in a non-interactive shell). Your local result above stands.",
|
|
353
|
+
"send.degraded.declined": "No external send: you declined. Your local result above stands.",
|
|
354
|
+
"send.degraded.generic": "The external model could not be used ({reason}) — falling back to your local result above. Nothing was fabricated. (model: {model})",
|
|
355
|
+
// --dry-run-send: print the exact redacted payload, send nothing.
|
|
356
|
+
"send.dryRun.head": "--dry-run-send: the EXACT redacted payload that WOULD be sent (nothing was sent, no model was called):",
|
|
357
|
+
"send.dryRun.note": "Review it below. Every sensitive value is masked; the prompt would travel on stdin to the model.",
|
|
358
|
+
|
|
359
|
+
// ---- dialogue scan (the LOCAL half of semantic scanning) ----
|
|
360
|
+
// Transparency header (red line #5): printed at the top of the report when a local
|
|
361
|
+
// dialogue/log export was read. Names the files + line counts + flagged-snippet
|
|
362
|
+
// total, then a stand-alone "all local, nothing sent" promise line.
|
|
363
|
+
"bootstrap.dialogue.head": "Read {count} local export{plural} you provided ({files}) — {snippets} snippet(s) flagged.",
|
|
364
|
+
"bootstrap.dialogue.localPromise": "These were read locally only, redacted before display, and NOTHING was sent anywhere.",
|
|
365
|
+
"bootstrap.dialogue.skippedHead": "Some files you named could not be read (skipped, not fatal):",
|
|
366
|
+
"bootstrap.dialogue.skipped.not_found": " - skipped {path} (not found)",
|
|
367
|
+
"bootstrap.dialogue.skipped.unreadable": " - skipped {path} (unreadable)",
|
|
368
|
+
"bootstrap.dialogue.skipped.not_a_file": " - skipped {path} (not a file)",
|
|
369
|
+
"bootstrap.dialogue.skipped.too_large": " - skipped {path} (too large)",
|
|
370
|
+
"bootstrap.dialogue.skipped.unsupported_type": " - skipped {path} (unsupported type — use .txt/.json/.md/.log)",
|
|
371
|
+
// VERIFY card, dialogue block: a clearly separated header + per-claim line. The
|
|
372
|
+
// wording "claimed in dialogue · not verified" is the honesty contract and is
|
|
373
|
+
// never softened; the snippet is already redacted.
|
|
374
|
+
"bootstrap.verify.dialogueHead": " From your chat (claimed in dialogue · not verified — NOT shown as done): {count} completion claim{plural} the ledger does not back:",
|
|
375
|
+
"bootstrap.verify.dialogueItem": " - {path}:{line} — “{snippet}”",
|
|
376
|
+
// HARVEST card, dialogue block: a separated header + per-candidate line. Proposed
|
|
377
|
+
// only; nothing is saved.
|
|
378
|
+
"bootstrap.harvest.dialogueHead": " From your chat (proposed — nothing saved): a standing preference you may want to record:",
|
|
379
|
+
"bootstrap.harvest.dialogueItem": " - you repeated this correction {count}× → propose a profile preference: “{snippet}”",
|
|
380
|
+
// Next-step branch when the only completion signal is a chat claim (no ledger gap):
|
|
381
|
+
// turn it into a real tracked task so the "done" stops being just words.
|
|
382
|
+
"bootstrap.next.dialogueClaim.text": "Next: your chat claims something is done that the ledger does not back — turn it into a tracked task + recorded run so the “done” is real.",
|
|
383
|
+
"bootstrap.next.dialogueClaim.cmd": " node bin/ai-collab.js task create --title \"...\"",
|
|
384
|
+
|
|
385
|
+
// ---- common errors (the most-hit failure paths) ----
|
|
386
|
+
"error.missingOption": "Missing --{name}.",
|
|
387
|
+
"error.missingTarget": "Missing --target. Run: node bin/ai-collab.js init --target <dir>",
|
|
388
|
+
"error.noWorkspace":
|
|
389
|
+
"No .aict workspace found at {where}. The run-layer commands operate an existing workspace. " +
|
|
390
|
+
"Create one first: node bin/ai-collab.js init --target <dir> (writes <dir>/.aict), then run from <dir> or pass --workspace <dir>/.aict.",
|
|
391
|
+
"error.noWorkspace.currentDir": "the current directory",
|
|
392
|
+
"error.taskNotFound.update": "Task {id} not found. Update only an existing task (run: node bin/ai-collab.js task create ...).",
|
|
393
|
+
"error.taskNotFound.evidence": "Task {id} not found. Add evidence only to an existing task (run: node bin/ai-collab.js task create ...).",
|
|
394
|
+
"error.taskNotFound.runStart": "Task {id} not found. Start a run only for an existing task.",
|
|
395
|
+
"error.taskNotFound.runExec": "Task {id} not found. Run a command only for an existing task.",
|
|
396
|
+
"error.taskNotFound.receipt": "Task {id} not found. Create a receipt only for an existing task.",
|
|
397
|
+
"error.taskNotFound.handoff": "Task {id} not found. Create a handoff draft for an existing task, or omit --task to cover the whole workspace.",
|
|
398
|
+
"error.taskNotFound.learning": "Task {id} not found. Bind a learning row only to an existing task (or omit --task).",
|
|
399
|
+
"error.doneNoEvidence": "Task {id} cannot be marked \"done\" with no evidence. Add evidence first (node bin/ai-collab.js evidence add --task {id} ...), or use blocked/partial/unverified.",
|
|
400
|
+
"error.taskStatusInvalid": "--status must be one of: {allowed} (got \"{got}\").",
|
|
401
|
+
"warn.doneNoReceipt": "Warning: task {id} marked done without an accepted receipt; this shows as author-marked, unverified — add evidence + a receipt to verify.",
|
|
402
|
+
|
|
403
|
+
// ---- run exec dangerous-command guard (B6a-1) ----
|
|
404
|
+
// A conservative, NARROW guard: only well-known destructive shapes trip it
|
|
405
|
+
// (so ordinary commands are rarely blocked — narrow false positives possible,
|
|
406
|
+
// --yes overrides). On a TTY it asks y/N (default N).
|
|
407
|
+
// Without a TTY it REFUSES unless --yes/--force is passed. Nothing is executed
|
|
408
|
+
// or recorded on a refusal.
|
|
409
|
+
"danger.header": "DANGEROUS COMMAND — this matches a known destructive pattern.",
|
|
410
|
+
"danger.matched": " matched: {patterns}",
|
|
411
|
+
"danger.command": " command: {command}",
|
|
412
|
+
"danger.prompt": "Run it anyway? [y/N] ",
|
|
413
|
+
"danger.declined": "Refused: dangerous command not run (you answered no). Nothing recorded.",
|
|
414
|
+
"danger.refusedNonTty": "Refused: this command matches a known destructive pattern ({patterns}) and there is no interactive terminal to confirm. Re-run with --yes (or --force) to run it anyway. Nothing recorded.",
|
|
415
|
+
|
|
416
|
+
// ---- --help levels (the full L0-L4 reference; honesty caveats verbatim) ----
|
|
417
|
+
"help.levels": `Guard levels (L0-L4)
|
|
418
|
+
|
|
419
|
+
Plain version: a guard level grades the EVIDENCE behind a "done", and caps how strong a
|
|
420
|
+
verdict it can earn. The more — and the more INDEPENDENT — the evidence, the higher the
|
|
421
|
+
level. A single tool, reviewing its own work, tops out at L2 ("pass with risk"); a clean
|
|
422
|
+
"pass" needs a second, DIFFERENT model family to re-check it (L3); the strongest local pass
|
|
423
|
+
(L4) also needs that reviewer to actually re-run the command and have it match a recorded run.
|
|
424
|
+
You never type the level in — the CLI computes it from the evidence you cite.
|
|
425
|
+
|
|
426
|
+
The level is COMPUTED by the CLI from your --review-mode + the evidence cited — it
|
|
427
|
+
is NOT something you declare. --claimed-level (a.k.a. the legacy --guard-level) is
|
|
428
|
+
only used to warn you if you claimed more than the evidence supports; the recorded
|
|
429
|
+
level is always the computed one.
|
|
430
|
+
L0 summary only -> insufficient_evidence only
|
|
431
|
+
L1 artifact, no real run -> cannot pass
|
|
432
|
+
L2 single-tool OR same-family sub-agent (advisory) -> at most pass_with_risk
|
|
433
|
+
L2.5 same tool, different model (weak L3) -> at most pass_with_risk
|
|
434
|
+
L3 cross-family review (self-declared) -> may pass, marked unverified
|
|
435
|
+
L4 cross-family review AND a reviewer rerun reconciled to a recorded run exec -> strongest local pass
|
|
436
|
+
How the level is earned: review-mode sets a ceiling (self/same_family_subagent -> L2,
|
|
437
|
+
same_tool_other_model -> L2.5, cross_family -> L3, cross_family_rerun -> L4) and the
|
|
438
|
+
evidence caps it (a cross_family_guard row enables L3; L4 needs BOTH that cross_family_guard
|
|
439
|
+
row AND a rerun row that REFERENCES a RECONCILED recorded run exec — same task, finished,
|
|
440
|
+
executed:true, matching exitCode + command + outputSha256. A reconciled rerun on its OWN is
|
|
441
|
+
single-tool run evidence — only L2).
|
|
442
|
+
The real level is the LOWER of the two — so opening your OWN same-family sub-agent can
|
|
443
|
+
never reach L3 no matter what you claim, and a cross-family claim with no reconciled
|
|
444
|
+
rerun tops out at "L3 (self-declared cross-family, unverified)". A reconciled rerun with no
|
|
445
|
+
cross-family review is just the author re-running their own command — it stays L2, never L4.
|
|
446
|
+
IMPORTANT — family honesty: the model family on a cross_family_guard row is SELF-DECLARED.
|
|
447
|
+
This tool runs locally and CANNOT verify it, so an L3 is shown as "self-declared cross-family,
|
|
448
|
+
unverified". L4 is harder — it must reference a RECORDED run exec (runs.jsonl) whose exitCode +
|
|
449
|
+
command + outputSha256 reconcile — but it is still a LOCAL-trust pass: a single user can choose
|
|
450
|
+
and run a local command (and a hand-edited ledger can set any field), so L4 means "backed by a
|
|
451
|
+
recorded, output-matched local run", NOT cryptographic verification. (None of these fields are
|
|
452
|
+
anti-forgery proof; they record who/what claimed what.)
|
|
453
|
+
|
|
454
|
+
Network: not used.
|
|
455
|
+
`,
|
|
456
|
+
|
|
457
|
+
// ---- --help (the main term-light reference). Command SYNTAX stays verbatim in
|
|
458
|
+
// both languages (it is what the user types); prose is faithfully translated.
|
|
459
|
+
"help.main": `AI Collaboration Open System
|
|
460
|
+
|
|
461
|
+
Source on GitHub (CI green); not published to npm yet: run from a clone with node bin/ai-collab.js <command>.
|
|
462
|
+
The global ai-collab command shown below becomes available after publish.
|
|
463
|
+
|
|
464
|
+
New here? These three commands cover most of what you need (plain-language first):
|
|
465
|
+
init Create your workspace — one folder of plain files you keep. Start here.
|
|
466
|
+
bootstrap Look at your OWN recent work and print a read-only "where you stand" report. Your AI is instructed to run this for you on its first reply (whether it does depends on your tool loading the rule — see first-run); you can also run it yourself anytime for a read-only baseline.
|
|
467
|
+
status Show what is open, what is done, and one suggested next step. Run this any time to get your bearings.
|
|
468
|
+
Full command list is below. Guard levels (L0-L4) and the cross-family theory live at the very end — run "node bin/ai-collab.js --help levels" to read just that.
|
|
469
|
+
|
|
470
|
+
Usage (after publish; before publish prefix each with "node bin/ai-collab.js "):
|
|
471
|
+
ai-collab init --target <dir> [--dry-run] [--force]
|
|
472
|
+
ai-collab welcome [--lang <en|zh>] # print the fixed onboarding intro your AI shows you after install
|
|
473
|
+
ai-collab guide
|
|
474
|
+
ai-collab demo
|
|
475
|
+
ai-collab bootstrap [--workspace <dir>] [--report-only] [--json] [--yes] [--dialogue <path[,path]>] [--logs <path[,path]>]
|
|
476
|
+
ai-collab check --workspace <dir>
|
|
477
|
+
ai-collab adapters install --target <dir> [--tool <list>] [--enable-hooks] [--dry-run] [--force]
|
|
478
|
+
|
|
479
|
+
Run layer (operate the loop on real tasks; all take --workspace <dir>; without it they
|
|
480
|
+
use ./.aict here, and refuse with init guidance if no workspace exists yet — never write a stray ./state):
|
|
481
|
+
ai-collab task create --title "..."
|
|
482
|
+
ai-collab task update --task <id> --status <open|done|blocked|partial|unverified>
|
|
483
|
+
ai-collab evidence add --task <id> --kind <k> --summary "..." [--detail "..."]
|
|
484
|
+
kind rerun also needs: --command "<cmd>" --exit <code> --output "<captured output>" [--run <runId>] [--runner "<name>"]
|
|
485
|
+
(--run links to a recorded run in runs.jsonl; REQUIRED for the rerun to reach L4 —
|
|
486
|
+
the run must be a finished run exec for the same task and agree on exitCode + command + output)
|
|
487
|
+
kind cross_family_guard also needs: at least one of --reviewer "<who>" / --family "<model-family>" / --ref "<source>"
|
|
488
|
+
ai-collab run start --task <id> [--command "..."] # RECORD a run you report (does not execute)
|
|
489
|
+
ai-collab run finish --task <id> --exit <code> # RECORD the exit code you report
|
|
490
|
+
ai-collab run exec --task <id> --command "..." [--cwd <dir>] [--clean-env] # ACTUALLY run it locally + record the REAL exit (executed:true)
|
|
491
|
+
Runs in the workspace's project root by default (NOT your current shell directory); --cwd <dir> overrides it. The
|
|
492
|
+
directory it ran in is recorded on the run and printed, so the evidence shows exactly where the command executed.
|
|
493
|
+
Safety: 'run exec' runs a real shell command locally — read the command first, especially if an AI suggested it.
|
|
494
|
+
A NARROW set of known-destructive shapes (rm -rf, sudo, fork bombs, curl|sh, dd, mkfs, > /dev/, chmod -R 777, redirects
|
|
495
|
+
into system paths) trips a guard: on an interactive terminal it asks y/N (default N); with no terminal it REFUSES unless
|
|
496
|
+
you pass --yes (or --force). Ordinary commands are rarely affected (narrow false positives possible; a
|
|
497
|
+
danger word quoted as data or used as an argument is ignored; --yes overrides), and a refusal records nothing.
|
|
498
|
+
--clean-env runs the command with a MINIMAL environment (PATH/HOME + locale/temp basics only) instead of inheriting
|
|
499
|
+
your full environment, so a suggested command cannot read your API keys/tokens. Default (no flag) inherits the full
|
|
500
|
+
environment, unchanged. Whether the run was clean-env is recorded on the run (cleanEnv) and printed.
|
|
501
|
+
ai-collab receipt create --task <id> --verdict <pass|reject|insufficient_evidence|pass_with_risk> [--review-mode <self|same_family_subagent|same_tool_other_model|cross_family|cross_family_rerun>] [--claimed-level <L0|L1|L2|L2.5|L3|L4>] [--evidence <id,id>] [--rerun <id,id>]
|
|
502
|
+
ai-collab receipt accept --id <receiptId> --owner [name]
|
|
503
|
+
ai-collab learning add --type <harvest|profile> --content "..." [--task <id>]
|
|
504
|
+
ai-collab learning confirm --id <id> # keep it as written
|
|
505
|
+
ai-collab learning edit --id <id> --content "..." # reword and keep
|
|
506
|
+
ai-collab learning drop --id <id> # discard it
|
|
507
|
+
ai-collab status [--workspace <dir>] [--json]
|
|
508
|
+
ai-collab handoff create [--task <id>] [--workspace <dir>] [--json]
|
|
509
|
+
Generate a DRAFT handoff note from the ledger (.aict/handoff/handoff-*.md) so the next session/tool resumes
|
|
510
|
+
without re-explaining. Only tasks with an ACCEPTED receipt are listed as Done; pass_with_risk / pending /
|
|
511
|
+
unverified work goes under Unverified. The draft is a starting point to review and complete, not a finished handoff.
|
|
512
|
+
ai-collab capability detect [--project <dir>] [--tools <list>] [--families <list>] [--subagents] [--can-switch-model] [--can-rerun] [--no-new-conversation] [--json]
|
|
513
|
+
|
|
514
|
+
bootstrap: the scan engine your AI uses to onboard you. The first time you work
|
|
515
|
+
with it after install, your AI is instructed to run this to look at your recent
|
|
516
|
+
work (whether it does depends on your tool loading the rule — see the first-run
|
|
517
|
+
section); you can also run it yourself anytime for a read-only
|
|
518
|
+
baseline. It reads your OWN recent work --
|
|
519
|
+
your repo structure, your recent git history (read-only), your .aict ledger, and
|
|
520
|
+
your AI instruction files -- and prints one plain "AI collaboration baseline" with
|
|
521
|
+
five cards: PROFILE CLUES (signals from your setup -- detected tools,
|
|
522
|
+
recently changed file types -- as clues for your AI to confirm with you, never a
|
|
523
|
+
conclusion bootstrap reached), VERIFY (which "done"s cannot be trusted yet -- pending, risk-not-
|
|
524
|
+
signed-off, or self-declared cross-family reviews -- recomputed by the same honest
|
|
525
|
+
rules as status/handoff, never shown as done), RESUME (your in-progress tasks, a
|
|
526
|
+
missing handoff, files you keep re-touching), ROLES (high-risk KEYWORDS scanned in your work
|
|
527
|
+
mapped to existing helper roles like red-team / dual-guard -- a fact that a risk
|
|
528
|
+
word appears, with your AI confirming whether it truly applies, never a risk
|
|
529
|
+
verdict), and HARVEST (confirmed lessons you
|
|
530
|
+
can carry forward). It is DETERMINISTIC and local: no external model, no guessing,
|
|
531
|
+
nothing leaves your machine, and it WRITES NOTHING (report-only). It prints the
|
|
532
|
+
scan scope first and needs --yes to proceed (--yes skips that confirmation for
|
|
533
|
+
scripts). An empty/example-only workspace honestly says "no data of your own yet".
|
|
534
|
+
Optional, OFF by default: --dialogue <path> / --logs <path> read a LOCAL chat/log
|
|
535
|
+
export YOU name (comma-separate several) and add deterministic, redacted findings —
|
|
536
|
+
a chat "done" the ledger does not back is listed "claimed in dialogue · not
|
|
537
|
+
verified" (never shown done), and a correction you repeated becomes a PROPOSED
|
|
538
|
+
profile candidate (nothing saved). Still local, still no model, still no network.
|
|
539
|
+
|
|
540
|
+
Guard levels (L0-L4) grade the evidence behind a "done" and cap the verdict it may earn.
|
|
541
|
+
In one line: more / more-independent evidence -> a higher level -> a stronger pass; a single
|
|
542
|
+
tool tops out at L2 (pass_with_risk), and a plain "pass" needs an L3+ cross-family review.
|
|
543
|
+
The level is COMPUTED by the CLI from your evidence — you never declare it (--claimed-level,
|
|
544
|
+
a.k.a. the legacy --guard-level, only warns when you claim more than the evidence supports).
|
|
545
|
+
For the full L0-L4 ladder, how each level is earned, and the family-honesty caveats, run:
|
|
546
|
+
node bin/ai-collab.js --help levels
|
|
547
|
+
A pass_with_risk receipt is created "pending" and needs "receipt accept --owner [name]" to be accepted.
|
|
548
|
+
Owner acceptance records a local human sign-off (actor + timestamp) — a collaboration audit trail, not a cryptographic signature.
|
|
549
|
+
|
|
550
|
+
Capability detect: a DIFFERENT question from a receipt's guard level. A receipt says what THIS task EARNED;
|
|
551
|
+
"capability detect" says how high your SETUP could EVER score — your ceiling. It probes the project for tool
|
|
552
|
+
markers (.claude/, .codex/, .cursor/, AGENTS.md, …) and takes self-report flags (--tools / --families /
|
|
553
|
+
--subagents / --can-switch-model / --can-rerun) because the CLI cannot see which AI you installed. The
|
|
554
|
+
load-bearing judge is the number of DISTINCT model families you can bring, NOT tool count: two same-family
|
|
555
|
+
tools share blind spots (still L2); a SECOND, different family is the gate to a clean pass (L3); re-running the
|
|
556
|
+
commands yourself on top of that reaches L4. It then prints the single most valuable step to raise the ceiling.
|
|
557
|
+
CEILING is not ACHIEVED: the ceiling is the most your tools could support; each task still has to earn its level
|
|
558
|
+
with the evidence it cites. Project signals are INFERENCE, not proof (a marker file does not pin a model family),
|
|
559
|
+
so confirm with --tools / --families.
|
|
560
|
+
|
|
561
|
+
Learning ledger: capture what a task taught you, so the next task starts ahead. "learning add" proposes one
|
|
562
|
+
lesson (--type harvest) or one standing preference (--type profile); it lands as "proposed" until you keep it
|
|
563
|
+
(learning confirm), reword and keep it (learning edit), or discard it (learning drop). Only confirmed/edited
|
|
564
|
+
rows graduate into your long-term profile — nothing on the AI's say-so alone. Keep it to at most one harvest +
|
|
565
|
+
one profile per task. "status" then echoes back the ONE preference you most recently confirmed, so it feels
|
|
566
|
+
like the tool is learning how you work without you maintaining a system.
|
|
567
|
+
|
|
568
|
+
--tool selects which AI tools get an instruction file. Values: cursor, codex,
|
|
569
|
+
claude, copilot, cline, windsurf, all, auto (comma-separated for several).
|
|
570
|
+
Default auto installs only tools detected in the target; if none are detected
|
|
571
|
+
it writes nothing and asks you to pass --tool. Use --tool all for all six.
|
|
572
|
+
|
|
573
|
+
Three adaptation tiers, least to most invasive:
|
|
574
|
+
1. rules (default, always safe) -- the per-tool instruction file --tool writes.
|
|
575
|
+
2. skills (optional) -- the reusable ability cards in .aict/skills/
|
|
576
|
+
(created by init), loaded into a tool on demand.
|
|
577
|
+
3. hooks (opt-in, off by default) -- --enable-hooks adds ONE project-LOCAL Claude
|
|
578
|
+
Code Stop hook that reminds you to capture a
|
|
579
|
+
receipt at a completion claim. Never a global
|
|
580
|
+
hook; the install lists every file first and is
|
|
581
|
+
removable. Applies to --tool claude only.
|
|
582
|
+
|
|
583
|
+
First experience (recommended):
|
|
584
|
+
init -> open .aict/walkthroughs/10-minute-your-task.md -> run one full loop on your own real task
|
|
585
|
+
(want to watch the flow on a prepared example first? open .aict/walkthroughs/10-minute.md instead)
|
|
586
|
+
|
|
587
|
+
Run now (before publish):
|
|
588
|
+
node bin/ai-collab.js init --dry-run # preview only, writes nothing
|
|
589
|
+
node bin/ai-collab.js init --target ./my-ai-workspace # write the workspace
|
|
590
|
+
|
|
591
|
+
Network: not used.
|
|
592
|
+
`
|
|
593
|
+
},
|
|
594
|
+
|
|
595
|
+
zh: {
|
|
596
|
+
// ---- shared / cross-cutting ----
|
|
597
|
+
"common.networkNotUsed": "网络:未使用。",
|
|
598
|
+
"common.untitled": "(无标题)",
|
|
599
|
+
|
|
600
|
+
// ---- guard-level plain language (honesty ladder — faithful, not softened) ----
|
|
601
|
+
"level.L0": "仅有摘要——证据不足以通过",
|
|
602
|
+
"level.L1": "证据太薄·不算通过——请补一次真实运行/输出",
|
|
603
|
+
"level.L2": "单工具自查·只能睁眼接受风险",
|
|
604
|
+
"level.L2_5": "同工具换模型·弱跨族——仍是单一家族,接受需带风险",
|
|
605
|
+
"level.L3": "跨族复核·但家族系自报——由另一模型家族复查(自报)",
|
|
606
|
+
"level.L4": "本地最强·真执行并已对账复核——跨族复核外加一次已对账的重跑",
|
|
607
|
+
"marker.selfDeclaredCrossFamily": "自报跨族·未经验证",
|
|
608
|
+
|
|
609
|
+
// ---- welcome (主动引导介绍——CLI 原样硬打印 · Owner 锁定第四稿一字不改) ----
|
|
610
|
+
"welcome.intro":
|
|
611
|
+
"✅ 协作升级包已装好\n" +
|
|
612
|
+
"\n" +
|
|
613
|
+
"你刚给你的 AI 工具(Claude Code / Cursor / Codex 等)装了一套本地协作框架——\n" +
|
|
614
|
+
"相当于给 AI 配了套\"脚手架\",让它更靠谱、更懂你,而不是每次从零开始。\n" +
|
|
615
|
+
"工具本身不联网、不上传,你的资料只留在本地;只有你让我\"扫一眼你的活\"那一下,\n" +
|
|
616
|
+
"是我这个 AI 来读、跟你平时聊天一样过一下服务商——工具自己不传任何东西。\n" +
|
|
617
|
+
"\n" +
|
|
618
|
+
"【给你的 AI 加了六层能力】\n" +
|
|
619
|
+
" 画像 给你建立一份本地的个人画像,越用越懂你\n" +
|
|
620
|
+
" 上下文 给每一个任务建立档案,跨对话也能接着干\n" +
|
|
621
|
+
" 验收 动手前先讲清\"做成什么样才算完成\",免得 AI 理解偏\n" +
|
|
622
|
+
" 守卫 说\"做完了\"前先拿证据,还能拉第二个 AI 复核\n" +
|
|
623
|
+
" 交接 换工具/换对话不用重讲背景\n" +
|
|
624
|
+
" 收割 把有价值的经验沉淀下来,下次复用\n" +
|
|
625
|
+
"\n" +
|
|
626
|
+
"【你会明显感觉到的变化】\n" +
|
|
627
|
+
" · AI 不再嘴上\"搞定了\"实际没做完——必须拿证据自证\n" +
|
|
628
|
+
" · 重要决策有双守卫复核,不是一个 AI 说了算\n" +
|
|
629
|
+
" · 换对话/换工具,背景不丢\n" +
|
|
630
|
+
" · 卡壳时能帮你理清思路\n" +
|
|
631
|
+
"\n" +
|
|
632
|
+
"【想不通时,直接说关键词,AI 切到对应模式帮你想】\n" +
|
|
633
|
+
" 说\"碰撞模式\" → AI 跟你对撞观点、挑逻辑漏洞,把模糊想法聊清楚\n" +
|
|
634
|
+
" 说\"扫描盲区\" → AI 从外部视角找你没看到的死角\n" +
|
|
635
|
+
" 说\"红队\" → AI 专挑你方案的毛病\n" +
|
|
636
|
+
" (还有双守卫复核、根因分析等,需要时说一声)\n" +
|
|
637
|
+
"\n" +
|
|
638
|
+
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +
|
|
639
|
+
"先别急着干活——现在花 30 秒,我带你亲眼看看它能帮你什么。\n" +
|
|
640
|
+
"我这就扫一眼你最近的活,当场给你指出:\n" +
|
|
641
|
+
" · 哪些你以为\"做完\"的活,其实没留验证证据(最容易踩的坑)\n" +
|
|
642
|
+
" · 你最近碰的高风险任务,该拉哪些帮手角色(红队/双守卫)把关\n" +
|
|
643
|
+
" · 从你的活里看出的工作习惯画像(你确认或改,不用填表)\n" +
|
|
644
|
+
" · 这次值得存下来的经验\n" +
|
|
645
|
+
"你什么都不用做,回我一句\"扫吧\"我就开始,试完你就知道它值在哪——现在就让我扫一眼吗?",
|
|
646
|
+
|
|
647
|
+
// ---- init (writing) ----
|
|
648
|
+
"init.created.title": "AI 协作开放系统工作区已创建。",
|
|
649
|
+
"init.created.body":
|
|
650
|
+
"工作区:{workspaceRoot}\n" +
|
|
651
|
+
"START_HERE.md:{startHere}\n" +
|
|
652
|
+
"已写入文件:{files}\n" +
|
|
653
|
+
"{backupLine}{network}\n" +
|
|
654
|
+
"为什么有效:AI 生产力是乘积而非加总——本系统补上原始模型能力之外的各项因子(画像、上下文、验收、守卫、交接、收割)。详见 docs/WHY_THIS_EXISTS.md。\n" +
|
|
655
|
+
"第一次回复时,你的 AI 被指示主动提出扫描你最近的工作、并演示它带来什么改变(是否真这样做取决于你的工具有没有加载这条规则)——这一步你不用自己运行任何东西。想现在自己就要一份只读基线?运行:node bin/ai-collab.js bootstrap --yes(本地「AI 协作基线」报告——不写入也不发送任何东西到任何地方)。\n" +
|
|
656
|
+
"下一步:打开 {walkthroughYourTask},在你自己的一个真实任务上跑完整一圈(或先打开 {walkthrough} 看预置示例的流程)。",
|
|
657
|
+
"init.backupLine": "备份:{backupPath}\n",
|
|
658
|
+
"init.dryRun.title": "试运行。未写入任何文件。",
|
|
659
|
+
"init.dryRun.body":
|
|
660
|
+
"工作区:{workspaceRoot}\n" +
|
|
661
|
+
"计划写入文件:{files}\n" +
|
|
662
|
+
"已存在工作区:{existing}\n" +
|
|
663
|
+
"{defaultTargetLine}{network}",
|
|
664
|
+
"init.dryRun.existing.yes": "是",
|
|
665
|
+
"init.dryRun.existing.no": "否",
|
|
666
|
+
"init.dryRun.defaultTargetLine":
|
|
667
|
+
"未给定 --target;已对默认目标 {target} 做预览。若要写入,请运行:node bin/ai-collab.js init --target <dir>\n",
|
|
668
|
+
|
|
669
|
+
// ---- status ----
|
|
670
|
+
"status.title": "工作区状态",
|
|
671
|
+
"status.state": "状态目录:{stateDir}",
|
|
672
|
+
"status.tasks": "任务:{count} [{breakdown}]{seedNote}",
|
|
673
|
+
"status.evidence": "证据:{count}{seedNote}",
|
|
674
|
+
"status.runs": "运行:{count} [{breakdown}]{seedNote}",
|
|
675
|
+
"status.receipts": "回执:{count} [{breakdown}]{seedNote}",
|
|
676
|
+
"status.learning": "待定学习项:{count}",
|
|
677
|
+
"status.yourTasks": "你的任务:",
|
|
678
|
+
"status.seedNote.tasks": " (含 {count} 个示例种子——删掉它,换成你自己的)",
|
|
679
|
+
"status.seedNote.generic": " (含 {count} 个示例种子)",
|
|
680
|
+
"status.taskLine.head": " - {id} {title} [{status}]{seedTag}",
|
|
681
|
+
"status.taskLine.seedTag": " [示例种子]",
|
|
682
|
+
"status.display.authorMarkedDone": "完成——作者自标·未经验证",
|
|
683
|
+
"status.taskLine.receipt": " 回执 {id}:{verdict} · {level} · {status}{acceptedBy}{unverified}{plainNote}",
|
|
684
|
+
"status.taskLine.receipt.acceptedBy": " 由 {who} 签收",
|
|
685
|
+
"status.taskLine.receipt.unverified": "(自报跨族·未经验证)",
|
|
686
|
+
"status.taskLine.receipt.plainNote": "\n ({level}:{plain})",
|
|
687
|
+
"status.taskLine.receipt.none": " 回执:(暂无)",
|
|
688
|
+
"status.taskLine.counts": " 证据:{evidence} · 运行:{runs}",
|
|
689
|
+
"status.handoffLine": "交接草稿:{count} 份(最新:{latest})——交接前请先复核",
|
|
690
|
+
"status.carryLine": "正在带上你已确认的偏好:{content}",
|
|
691
|
+
"status.harvestLine": "你最近保留的收割心得:{content}",
|
|
692
|
+
"status.mostRecentActivity": "最近活动:{latest}",
|
|
693
|
+
"status.noActivity": "(暂无活动)",
|
|
694
|
+
"status.nextStep.withCommand": "下一步:{text}\n {command}",
|
|
695
|
+
"status.nextStep.textOnly": "下一步:{text}",
|
|
696
|
+
"status.next.noOwnWork.text": "你还没有自己的工作——先看看你最近的工作处在什么位置,或新建一个任务。",
|
|
697
|
+
"status.next.noEvidence.text": "任务 {id} 还没有任何证据——运行它的命令并记录真实结果。",
|
|
698
|
+
"status.next.noReceipt.text": "任务 {id} 有证据但没有回执——把守卫判定登记下来。",
|
|
699
|
+
"status.next.pending.text": "任务 {taskId} 上的回执 {receiptId} 正等你签字——签收它(或加一次跨族复核以达到 L3)。",
|
|
700
|
+
"status.next.missingHandoff.text": "你的工作已记录,但还没有交接草稿——生成一份,好让下一个会话/工具接得上。",
|
|
701
|
+
"status.next.keepLesson.text": "你有一条候选心得({id})——保留它,让它带得下去。",
|
|
702
|
+
"status.next.allClear.text": "你的所有任务都已有证据、已签字、已交接——没有未结项。准备好就开新任务。",
|
|
703
|
+
|
|
704
|
+
// ---- bootstrap report ----
|
|
705
|
+
"bootstrap.report.title": "你的 AI 协作基线(来自你自己最近的工作)",
|
|
706
|
+
"bootstrap.report.scanned": "本地扫描:{repoRoot}",
|
|
707
|
+
"bootstrap.report.readonly": "只读。没有任何东西离开过这台机器。",
|
|
708
|
+
"bootstrap.empty.line1": "你还没有记录任何自己的工作——目前只有内置示例。",
|
|
709
|
+
"bootstrap.empty.line2": "所以没有属于你的内容可报告。要得到真实基线:",
|
|
710
|
+
"bootstrap.empty.step1": " 1. 在循环里跑一个真实任务(见 `guide`)。",
|
|
711
|
+
"bootstrap.empty.step2": " 2. 重新运行 `bootstrap`,它就会报告你自己的工作。",
|
|
712
|
+
"bootstrap.empty.note": "(示例种子被刻意排除——那不是你的成果。)",
|
|
713
|
+
// PROFILE 卡(仅确定性线索——不下语义结论)。每一行都是本地扫描得到的事实;
|
|
714
|
+
// 末尾固定一句说明诚实边界:这些是线索、交给你自己的 AI 去和你确认,不是 bootstrap 下的结论。
|
|
715
|
+
"bootstrap.profile.title": "画像线索——来自你的配置的信号(不是结论)",
|
|
716
|
+
"bootstrap.profile.tools": " 检测到你在用:{tools}。",
|
|
717
|
+
"bootstrap.profile.multiTool": " (配置了不止一个工具——一个跨工具协作的信号。)",
|
|
718
|
+
"bootstrap.profile.noTools": " 这里还没检测到任何 AI 指令文件。",
|
|
719
|
+
"bootstrap.profile.fileTypes": " 最近改动的文件类型:{names}。",
|
|
720
|
+
"bootstrap.profile.testScript": " 你的 package.json 里有 test 脚本。",
|
|
721
|
+
"bootstrap.profile.footer": " 这些是线索,不是结论。你的 AI 会据此跟你确认完整的工作习惯画像。",
|
|
722
|
+
// ROLES 卡(确定性关键词匹配 -> 已有的角色包)。它陈述一个事实(出现了高风险词)
|
|
723
|
+
// 加一个固定映射到角色;它从不判定这活就是有风险——那是你自己 AI 的事。角色名带大白话比喻。
|
|
724
|
+
"bootstrap.roles.title": "可以考虑的角色——来自你工作里的高风险关键词",
|
|
725
|
+
"bootstrap.roles.none": " 你最近的工作里没命中高风险关键词。(只是关键词扫描——不代表活就低风险;拿不准就问你的 AI 要不要上守卫角色。)",
|
|
726
|
+
"bootstrap.roles.intro": " 发现 {count} 个高风险信号(这些是关键词命中——是否真的适用由你的 AI 确认):",
|
|
727
|
+
"bootstrap.roles.item": " - “{subject}” 命中关键词 “{keyword}” → 建议 {roles}。",
|
|
728
|
+
"bootstrap.roles.roleJoin": " + ",
|
|
729
|
+
"bootstrap.roles.role.red-team": "red-team(红队——专门挑刺、找漏洞的人)",
|
|
730
|
+
"bootstrap.roles.role.dual-guard": "dual-guard(双守卫——另一个不同的 AI 再复核一遍)",
|
|
731
|
+
"bootstrap.roles.role.scout-review-controller": "scout-review-controller(SCOUT 取证——先把外部事实查清楚)",
|
|
732
|
+
"bootstrap.verify.title": "VERIFY——哪些『完成』暂时还不能信",
|
|
733
|
+
"bootstrap.verify.allClear1": " 目前没有任何过度声明。没有哪个『完成』在缺少证据的情况下",
|
|
734
|
+
"bootstrap.verify.allClear2": " 被当作已完成展示。",
|
|
735
|
+
"bootstrap.verify.count": " {count} 个『完成』声明暂时还不能当作已完成:",
|
|
736
|
+
"bootstrap.verify.item": " - {taskId} “{title}”:{reason}",
|
|
737
|
+
"bootstrap.verify.detail": " 明细:回执 {id} = {verdict} · {level} · {status}{marker}",
|
|
738
|
+
"bootstrap.verify.reason.pending_receipt": "已有复核但仍在待定——尚未签收",
|
|
739
|
+
"bootstrap.verify.reason.pass_with_risk_unaccepted": "只是带着一个尚无人签字确认的风险通过",
|
|
740
|
+
"bootstrap.verify.reason.self_declared_cross_family": "自报的跨族复核——本工具无法验证另一个模型是否真的检查过",
|
|
741
|
+
"bootstrap.verify.reason.author_marked_done": "作者自行标记完成·背后没有已签收的复核",
|
|
742
|
+
"bootstrap.resume.title": "RESUME——你在哪里、还缺什么",
|
|
743
|
+
"bootstrap.resume.noActive": " 目前没有你自己处于打开或进行中的任务。",
|
|
744
|
+
"bootstrap.resume.count": " {count} 个任务仍在进行中:",
|
|
745
|
+
"bootstrap.resume.item": " - {id} “{title}” [{status}]",
|
|
746
|
+
"bootstrap.resume.missingHandoff": " 还没有交接说明——下一个会话将从零开始。运行 `handoff create`。",
|
|
747
|
+
"bootstrap.resume.reTouch": " 你在最近的提交里反复改动同一批文件:{names}。",
|
|
748
|
+
"bootstrap.resume.reTouchNote": " (可能是『说完成了、还在打补丁』的信号——值得细看。)",
|
|
749
|
+
"bootstrap.resume.uncommitted": " 你有未提交的改动正在进行中。",
|
|
750
|
+
"bootstrap.harvest.title": "HARVEST——你可以带走什么",
|
|
751
|
+
"bootstrap.harvest.none1": " 暂时没有已确认可带走的内容。用 `learning confirm` 确认一条心得,",
|
|
752
|
+
"bootstrap.harvest.none2": " 它就会出现在这里。",
|
|
753
|
+
"bootstrap.harvest.candidate": " - {detail}(候选——不会自动保存任何东西)。",
|
|
754
|
+
"bootstrap.harvest.confirmedHead": " 已确认的学习项:",
|
|
755
|
+
"bootstrap.harvest.confirmedItem": " - ({type}){content}",
|
|
756
|
+
"bootstrap.harvest.detail.confirmed_learnings_ready": "{count} 条已确认的学习项,可带入你的下一个任务",
|
|
757
|
+
"bootstrap.harvest.detail.verified_done_tasks": "{count} 个任务达成了已验证(已签收)的结果——一个值得复用的模式",
|
|
758
|
+
"bootstrap.next.pending.text": "下一步:回执 {receiptId}(任务 {taskId})处于待定——你核对过后签收它,或用一次跨族复核来抬高它。",
|
|
759
|
+
"bootstrap.next.pending.cmd": " node bin/ai-collab.js receipt accept --id {receiptId} --owner you",
|
|
760
|
+
"bootstrap.next.selfCross.text": "下一步:任务 {taskId} 上的回执 {receiptId} 是一次本工具无法验证的自报跨族通过——你自己重跑一遍,用一次已记录的运行来支撑它。",
|
|
761
|
+
"bootstrap.next.selfCross.cmd": " node bin/ai-collab.js run exec --task {taskId} --command \"...\"",
|
|
762
|
+
"bootstrap.next.authorDone.text": "下一步:任务 {taskId} 被标记为完成但没有已签收的复核——补上证据并登记一份回执,让这个『完成』真正有支撑。",
|
|
763
|
+
"bootstrap.next.authorDone.cmd": " node bin/ai-collab.js receipt create --task {taskId} --verdict pass_with_risk --review-mode self --evidence <id>",
|
|
764
|
+
"bootstrap.next.missingHandoff.text": "下一步:生成一份交接草稿,好让下一个会话/工具无需从头解释就能接上。",
|
|
765
|
+
"bootstrap.next.missingHandoff.cmd": " node bin/ai-collab.js handoff create",
|
|
766
|
+
"bootstrap.next.keepLesson.text": "下一步:保留你提出的这条心得({id}),让它带入你的下一个任务。",
|
|
767
|
+
"bootstrap.next.keepLesson.cmd": " node bin/ai-collab.js learning confirm --id {id}",
|
|
768
|
+
"bootstrap.next.allClear.text": "下一步:继续在循环里跑真实任务;随时重新运行 `bootstrap` 获取更新后的基线。",
|
|
769
|
+
// 角色提示,在主下一步之后追加(高风险关键词命中时;它不替代 verify 动作)。建议性:指向已有的角色包。
|
|
770
|
+
"bootstrap.next.roles.text": "另外:你的工作里出现了高风险关键词——在你说『做完了』之前,考虑请上 {roles}。",
|
|
771
|
+
"bootstrap.consent.head": "bootstrap 将——在本地、只读地——读取以下内容来构建你的基线:",
|
|
772
|
+
"bootstrap.consent.repo": " - 你在 {repoRoot} 下的仓库结构(文件名、package.json 脚本)",
|
|
773
|
+
"bootstrap.consent.git": " - 本仓库里你最近的 git 历史(git log / git diff --stat)",
|
|
774
|
+
"bootstrap.consent.ledger": " - 你的 .aict 账本(任务、运行、证据、回执、学习项)",
|
|
775
|
+
"bootstrap.consent.ai": " - 你的 AI 指令文件(CLAUDE.md / AGENTS.md / .cursorrules / …)",
|
|
776
|
+
"bootstrap.consent.promise": "它不会调用任何外部模型,不做任何猜测,也不会把任何东西发送到任何地方。",
|
|
777
|
+
"bootstrap.consent.rerun": "加上 --yes 重新运行以确认并查看你的基线:",
|
|
778
|
+
"bootstrap.consent.cmd": " node bin/ai-collab.js bootstrap --yes",
|
|
779
|
+
// 仅在用户通过指定对话/日志文件主动开启时显示(连接器默认关闭)。诚实
|
|
780
|
+
// 提示——本地、确定性、已去敏——一并带上,让这次额外的高隐私读取绝不静默。
|
|
781
|
+
"bootstrap.consent.dialogue": " - 你指定的本地对话/日志导出:{files}(本地读取、已去敏、确定性——绝不发送到任何地方)",
|
|
782
|
+
|
|
783
|
+
// --- bootstrap --send-to-model(唯一会外发的路径)-----------------------
|
|
784
|
+
// 同意预览(发送前展示):到底有什么会离开这台机器。
|
|
785
|
+
"send.preview.head": "即将发送给外部模型——以下就是会发出去的全部内容:",
|
|
786
|
+
"send.preview.model": " 模型:{model} (提示通过 stdin 传入,绝不放在命令行上)",
|
|
787
|
+
"send.preview.count": " 来自你本地扫描的 {count} 条已去敏片段",
|
|
788
|
+
"send.preview.redacted": " 每条片段都已去敏(密钥 / 令牌 / 邮箱 / 本地路径已遮蔽),且整个负载在离开前会再核查一遍",
|
|
789
|
+
"send.preview.sources": " 来自:{files}",
|
|
790
|
+
"send.preview.promise": "除此之外什么都不发(不发原始文件、不发账本、不发仓库内容)。这是唯一一个会联系本机之外模型的功能。",
|
|
791
|
+
// 确认(交互式 TTY)。默认拒绝:只有明确输入 y/yes 才继续。
|
|
792
|
+
"send.confirm.prompt": "把这些已去敏的片段发给模型吗?[y/N] ",
|
|
793
|
+
// 非交互式拒绝(无 TTY 且无 --yes):什么都没发。
|
|
794
|
+
"send.refusedNonTty": "已拒绝:发送需要你确认。在非交互式 shell 里请用 --yes 重新运行以确认。什么都没发。",
|
|
795
|
+
// 用户在提示处拒绝。
|
|
796
|
+
"send.declined": "已拒绝——什么都没发。只显示你的本地结果。",
|
|
797
|
+
// LLM 候选块:明确标注为最低置信、仅建议、未验证。
|
|
798
|
+
"send.candidates.head": "来自外部模型——{count} 条建议(不属于你已验证的结果):",
|
|
799
|
+
"send.candidates.caveat": " ⚠ AI 建议 · 低置信 · 未验证 · 仅为建议——在信任或保存之前请逐条自行确认。这里的任何内容都没有被写入任何地方。",
|
|
800
|
+
"send.candidates.item": " - [{kind}] {summary}",
|
|
801
|
+
"send.candidates.basis": " 依据:{basis}",
|
|
802
|
+
"send.candidates.kind.false_completion": "声称已完成 · 未验证",
|
|
803
|
+
"send.candidates.kind.profile_candidate": "可能的长期偏好",
|
|
804
|
+
"send.candidates.kind.context_gap": "可能缺失的上下文",
|
|
805
|
+
"send.candidates.kind.harvest_candidate": "可能可复用的心得",
|
|
806
|
+
// 优雅降级行(模型未被使用 / 不可达)。
|
|
807
|
+
"send.degraded.no_redacted_snippets": "未外发:没有可发送的已去敏片段(请先用 --dialogue/--logs 提供对话/日志导出)。上面你的本地结果仍然有效。",
|
|
808
|
+
"send.degraded.consent_required_non_tty": "未外发:需要确认但未给出(在非交互式 shell 里需要 --yes)。上面你的本地结果仍然有效。",
|
|
809
|
+
"send.degraded.declined": "未外发:你拒绝了。上面你的本地结果仍然有效。",
|
|
810
|
+
"send.degraded.generic": "外部模型无法使用({reason})——回退到上面你的本地结果。没有任何东西被编造。(模型:{model})",
|
|
811
|
+
// --dry-run-send:打印将要发送的确切去敏负载,什么都不发。
|
|
812
|
+
"send.dryRun.head": "--dry-run-send:将要发送的确切去敏负载(什么都没发,没有调用任何模型):",
|
|
813
|
+
"send.dryRun.note": "在下方审阅。每个敏感值都已遮蔽;提示会通过 stdin 传给模型。",
|
|
814
|
+
|
|
815
|
+
// ---- 对话扫描(语义扫描的本地半)----
|
|
816
|
+
// 透明性头部(红线 #5):当读取了本地对话/日志导出时,打印在报告顶部。
|
|
817
|
+
// 列出文件 + 行数 + 命中片段总数,然后单独一行「全本地、未外发」承诺。
|
|
818
|
+
"bootstrap.dialogue.head": "读取了你提供的 {count} 个本地导出({files})——命中 {snippets} 条片段。",
|
|
819
|
+
"bootstrap.dialogue.localPromise": "这些只在本地读取,显示前已去敏,且没有任何东西被发送到任何地方。",
|
|
820
|
+
"bootstrap.dialogue.skippedHead": "你指定的部分文件无法读取(已跳过,不影响其余):",
|
|
821
|
+
"bootstrap.dialogue.skipped.not_found": " - 已跳过 {path}(未找到)",
|
|
822
|
+
"bootstrap.dialogue.skipped.unreadable": " - 已跳过 {path}(不可读)",
|
|
823
|
+
"bootstrap.dialogue.skipped.not_a_file": " - 已跳过 {path}(不是文件)",
|
|
824
|
+
"bootstrap.dialogue.skipped.too_large": " - 已跳过 {path}(太大)",
|
|
825
|
+
"bootstrap.dialogue.skipped.unsupported_type": " - 已跳过 {path}(不支持的类型——请用 .txt/.json/.md/.log)",
|
|
826
|
+
// VERIFY 卡 · 对话块:清晰分隔的头部 + 每条声明一行。措辞「来自对话的
|
|
827
|
+
// 声明 · 未验证」是诚实契约,绝不软化;片段已去敏。
|
|
828
|
+
"bootstrap.verify.dialogueHead": " 来自你的聊天(来自对话的声明 · 未验证——不显示为已完成):账本无法支撑的 {count} 条『完成』声明:",
|
|
829
|
+
"bootstrap.verify.dialogueItem": " - {path}:{line} —— “{snippet}”",
|
|
830
|
+
// HARVEST 卡 · 对话块:分隔的头部 + 每条候选一行。仅候选;不保存任何东西。
|
|
831
|
+
"bootstrap.harvest.dialogueHead": " 来自你的聊天(候选——不保存任何东西):一个你可能想记录的长期偏好:",
|
|
832
|
+
"bootstrap.harvest.dialogueItem": " - 你重复了这条纠正 {count} 次 → 建议记入一条 profile 偏好:“{snippet}”",
|
|
833
|
+
// 当唯一的『完成』信号来自聊天(账本没有对应缺口)时的下一步:把它变成
|
|
834
|
+
// 一个真实被跟踪的任务,让这个『完成』不再只是嘴上说说。
|
|
835
|
+
"bootstrap.next.dialogueClaim.text": "下一步:你的聊天声称某件事已完成,但账本无法支撑——把它变成一个被跟踪的任务 + 一次已记录的运行,让这个『完成』成为真的。",
|
|
836
|
+
"bootstrap.next.dialogueClaim.cmd": " node bin/ai-collab.js task create --title \"...\"",
|
|
837
|
+
|
|
838
|
+
// ---- common errors ----
|
|
839
|
+
"error.missingOption": "缺少 --{name}。",
|
|
840
|
+
"error.missingTarget": "缺少 --target。运行:node bin/ai-collab.js init --target <dir>",
|
|
841
|
+
"error.noWorkspace":
|
|
842
|
+
"在 {where} 未找到 .aict 工作区。运行层命令操作的是一个已存在的工作区。" +
|
|
843
|
+
"请先创建一个:node bin/ai-collab.js init --target <dir>(会写入 <dir>/.aict),然后从 <dir> 运行,或传 --workspace <dir>/.aict。",
|
|
844
|
+
"error.noWorkspace.currentDir": "当前目录",
|
|
845
|
+
"error.taskNotFound.update": "未找到任务 {id}。只能更新已存在的任务(运行:node bin/ai-collab.js task create ...)。",
|
|
846
|
+
"error.taskNotFound.evidence": "未找到任务 {id}。只能给已存在的任务添加证据(运行:node bin/ai-collab.js task create ...)。",
|
|
847
|
+
"error.taskNotFound.runStart": "未找到任务 {id}。只能为已存在的任务开始一次运行。",
|
|
848
|
+
"error.taskNotFound.runExec": "未找到任务 {id}。只能为已存在的任务运行命令。",
|
|
849
|
+
"error.taskNotFound.receipt": "未找到任务 {id}。只能为已存在的任务创建回执。",
|
|
850
|
+
"error.taskNotFound.handoff": "未找到任务 {id}。请为一个已存在的任务创建交接草稿,或省略 --task 以覆盖整个工作区。",
|
|
851
|
+
"error.taskNotFound.learning": "未找到任务 {id}。只能把学习项绑定到已存在的任务(或省略 --task)。",
|
|
852
|
+
"error.doneNoEvidence": "任务 {id} 在没有证据的情况下不能被标记为“done”。请先添加证据(node bin/ai-collab.js evidence add --task {id} ...),或改用 blocked/partial/unverified。",
|
|
853
|
+
"error.taskStatusInvalid": "--status 必须是以下之一:{allowed}(收到 \"{got}\")。",
|
|
854
|
+
"warn.doneNoReceipt": "警告:任务 {id} 在没有已签收回执的情况下被标记为完成;这会显示为作者自标·未经验证——请补上证据和一份回执来验证。",
|
|
855
|
+
|
|
856
|
+
// ---- run exec 危险命令护栏(B6a-1)----
|
|
857
|
+
// 一道保守、收窄的护栏:只有公认的破坏性写法才会触发(普通命令很少被拦——可能有少量误报,--yes 可覆盖)。
|
|
858
|
+
// 有交互终端时问 y/N(默认 N);没有交互终端时直接拒绝,除非带上 --yes/--force。
|
|
859
|
+
// 一旦拒绝,命令既不执行也不记账。
|
|
860
|
+
"danger.header": "危险命令——这条命中了一个已知的破坏性模式。",
|
|
861
|
+
"danger.matched": " 命中:{patterns}",
|
|
862
|
+
"danger.command": " 命令:{command}",
|
|
863
|
+
"danger.prompt": "仍然运行它?[y/N] ",
|
|
864
|
+
"danger.declined": "已拒绝:危险命令未运行(你回答了否)。未记录任何内容。",
|
|
865
|
+
"danger.refusedNonTty": "已拒绝:这条命令命中了一个已知的破坏性模式({patterns}),且当前没有交互终端可供确认。请带上 --yes(或 --force)重新运行以强制执行。未记录任何内容。",
|
|
866
|
+
|
|
867
|
+
// ---- --help levels(完整 L0-L4 参考;诚实限定词忠实保留,绝不软化)----
|
|
868
|
+
"help.levels": `守卫等级(L0-L4)
|
|
869
|
+
|
|
870
|
+
大白话:守卫等级评的是一个『完成』背后的证据,并据此给该证据所能挣得的判定设上限。证据越多、
|
|
871
|
+
越独立,等级越高。单一工具自查自己的工作,最高只到 L2(『带风险通过』);一个干净的『pass』
|
|
872
|
+
需要第二个、不同的模型家族来复查它(L3);本地最强的通过(L4)还需要那个复查者真的把命令重跑一遍,
|
|
873
|
+
并与一次已记录的运行对得上。等级你从不手动填——CLI 会根据你引用的证据计算出来。
|
|
874
|
+
|
|
875
|
+
等级由 CLI 根据你的 --review-mode + 所引用的证据计算得出——不是你声明的。
|
|
876
|
+
--claimed-level(即旧的 --guard-level)只用于在你声明的等级超过证据所能支撑时向你发出警告;
|
|
877
|
+
被记录下来的等级永远是计算出来的那个。
|
|
878
|
+
L0 仅有摘要 -> 只能是 insufficient_evidence
|
|
879
|
+
L1 有产物,但无真实运行 -> 不能通过
|
|
880
|
+
L2 单工具 或 同族子代理(建议性)-> 最多 pass_with_risk
|
|
881
|
+
L2.5 同工具、不同模型(弱 L3) -> 最多 pass_with_risk
|
|
882
|
+
L3 跨族复核(自报) -> 可以通过,但标记为未经验证
|
|
883
|
+
L4 跨族复核 且 复查者的重跑与一次已记录的 run exec 对账一致 -> 本地最强通过
|
|
884
|
+
等级如何挣得:review-mode 设定一个上限(self/same_family_subagent -> L2,
|
|
885
|
+
same_tool_other_model -> L2.5,cross_family -> L3,cross_family_rerun -> L4),
|
|
886
|
+
而证据为其封顶(一行 cross_family_guard 启用 L3;L4 同时需要那行 cross_family_guard
|
|
887
|
+
以及一行引用了已对账的已记录 run exec 的 rerun——同一任务、已完成、executed:true、
|
|
888
|
+
exitCode + command + outputSha256 都匹配。一次已对账的重跑单凭它自己只是单工具的运行证据——只到 L2)。
|
|
889
|
+
真实等级取两者中较低的那个——所以开你自己的同族子代理,无论你声明什么都永远到不了 L3;
|
|
890
|
+
而一个没有已对账重跑的跨族声明,最高只到『L3(自报跨族·未经验证)』。一次没有跨族复核的已对账重跑,
|
|
891
|
+
只不过是作者自己又把命令跑了一遍——它停在 L2,永远不会是 L4。
|
|
892
|
+
重要——家族诚实:cross_family_guard 那一行上的模型家族是自报的。本工具在本地运行,无法验证它,
|
|
893
|
+
所以一个 L3 会被显示为『自报跨族·未经验证』。L4 更难——它必须引用一次已记录的 run exec(runs.jsonl),
|
|
894
|
+
其 exitCode + command + outputSha256 都对账一致——但它仍然是一个本地信任级别的通过:单个用户可以自己挑选
|
|
895
|
+
并运行一条本地命令(而手工编辑过的账本可以把任何字段设成任意值),所以 L4 的含义是『有一次已记录、
|
|
896
|
+
输出已匹配的本地运行作为支撑』,而非密码学意义上的验证。(这些字段没有一个是防伪证明;它们只记录谁/什么声明了什么。)
|
|
897
|
+
|
|
898
|
+
网络:未使用。
|
|
899
|
+
`,
|
|
900
|
+
|
|
901
|
+
// ---- --help(主参考·术语轻量)。命令语法在两种语言里都按原样保留(那是用户要敲的内容);
|
|
902
|
+
// 散文部分忠实翻译,诚实限定词一律不软化。
|
|
903
|
+
"help.main": `AI 协作开放系统
|
|
904
|
+
|
|
905
|
+
源码在 GitHub(CI 绿);尚未发布到 npm:请从一个克隆里用 node bin/ai-collab.js <command> 运行。
|
|
906
|
+
下面展示的全局 ai-collab 命令会在发布后可用。
|
|
907
|
+
|
|
908
|
+
新来的?这三个命令覆盖了你大部分所需(大白话优先):
|
|
909
|
+
init 创建你的工作区——一个你自己保留的、装着纯文本文件的文件夹。从这里开始。
|
|
910
|
+
bootstrap 查看你自己最近的工作,并打印一份只读的「你处在什么位置」报告。第一次协作时你的 AI 被指示替你跑它(是否真跑取决于你的工具有没有加载这条规则——见 first-run);你也可以随时自己运行它,得到一份只读基线。
|
|
911
|
+
status 显示哪些是打开的、哪些已完成,以及一条建议的下一步。任何时候运行它来摸清方位。
|
|
912
|
+
完整命令列表在下方。守卫等级(L0-L4)和跨族理论放在最末尾——运行 "node bin/ai-collab.js --help levels" 只看那部分。
|
|
913
|
+
|
|
914
|
+
用法(发布后;发布前请在每条前面加上 "node bin/ai-collab.js "):
|
|
915
|
+
ai-collab init --target <dir> [--dry-run] [--force]
|
|
916
|
+
ai-collab welcome [--lang <en|zh>] # 打印安装后 AI 给你看的那段固定新手介绍
|
|
917
|
+
ai-collab guide
|
|
918
|
+
ai-collab demo
|
|
919
|
+
ai-collab bootstrap [--workspace <dir>] [--report-only] [--json] [--yes] [--dialogue <path[,path]>] [--logs <path[,path]>]
|
|
920
|
+
ai-collab check --workspace <dir>
|
|
921
|
+
ai-collab adapters install --target <dir> [--tool <list>] [--enable-hooks] [--dry-run] [--force]
|
|
922
|
+
|
|
923
|
+
运行层(在真实任务上操作这套循环;全部接受 --workspace <dir>;不给它时
|
|
924
|
+
就用这里的 ./.aict,若还没有工作区则以 init 指引拒绝——绝不写出一个游离的 ./state):
|
|
925
|
+
ai-collab task create --title "..."
|
|
926
|
+
ai-collab task update --task <id> --status <open|done|blocked|partial|unverified>
|
|
927
|
+
ai-collab evidence add --task <id> --kind <k> --summary "..." [--detail "..."]
|
|
928
|
+
kind 为 rerun 时还需要: --command "<cmd>" --exit <code> --output "<captured output>" [--run <runId>] [--runner "<name>"]
|
|
929
|
+
(--run 链接到 runs.jsonl 里一次已记录的运行;rerun 要达到 L4 时必需——
|
|
930
|
+
该运行必须是同一任务的一次已完成 run exec,且 exitCode + command + output 都一致)
|
|
931
|
+
kind 为 cross_family_guard 时还需要:--reviewer "<who>" / --family "<model-family>" / --ref "<source>" 至少其一
|
|
932
|
+
ai-collab run start --task <id> [--command "..."] # 记录一次你上报的运行(不执行)
|
|
933
|
+
ai-collab run finish --task <id> --exit <code> # 记录你上报的退出码
|
|
934
|
+
ai-collab run exec --task <id> --command "..." [--cwd <dir>] [--clean-env] # 真的在本地运行它 + 记录真实退出码(executed:true)
|
|
935
|
+
默认在工作区的项目根目录运行(不是你当前的 shell 目录);--cwd <dir> 可覆盖。它实际
|
|
936
|
+
运行所在的目录会被记录在该运行上并打印出来,所以证据会显示命令究竟在哪里执行。
|
|
937
|
+
安全:'run exec' 会在本地运行一条真实的 shell 命令——先读懂这条命令,尤其是当它由 AI 建议时。
|
|
938
|
+
一组收窄的已知破坏性写法(rm -rf、sudo、fork 炸弹、curl|sh、dd、mkfs、> /dev/、chmod -R 777、重定向到系统路径)
|
|
939
|
+
会触发护栏:有交互终端时问 y/N(默认 N);没有终端时直接拒绝,除非带上 --yes(或 --force)。普通命令很少受影响
|
|
940
|
+
(可能有少量误报;被引号当作数据、或作为参数而非命令本身的危险词会被忽略;--yes 可覆盖),一旦拒绝则不记录任何内容。
|
|
941
|
+
--clean-env 用一个最小环境(只有 PATH/HOME + 语言环境/临时目录这些基础项)来运行命令,而不是继承
|
|
942
|
+
你的完整环境,这样一条被建议的命令就读不到你的 API 密钥/令牌。默认(不加该标志)继承完整
|
|
943
|
+
环境,行为不变。该运行是否为 clean-env 会被记录在运行上(cleanEnv)并打印。
|
|
944
|
+
ai-collab receipt create --task <id> --verdict <pass|reject|insufficient_evidence|pass_with_risk> [--review-mode <self|same_family_subagent|same_tool_other_model|cross_family|cross_family_rerun>] [--claimed-level <L0|L1|L2|L2.5|L3|L4>] [--evidence <id,id>] [--rerun <id,id>]
|
|
945
|
+
ai-collab receipt accept --id <receiptId> --owner [name]
|
|
946
|
+
ai-collab learning add --type <harvest|profile> --content "..." [--task <id>]
|
|
947
|
+
ai-collab learning confirm --id <id> # 原样保留它
|
|
948
|
+
ai-collab learning edit --id <id> --content "..." # 改写后保留
|
|
949
|
+
ai-collab learning drop --id <id> # 丢弃它
|
|
950
|
+
ai-collab status [--workspace <dir>] [--json]
|
|
951
|
+
ai-collab handoff create [--task <id>] [--workspace <dir>] [--json]
|
|
952
|
+
从账本生成一份交接草稿(.aict/handoff/handoff-*.md),好让下一个会话/工具无需从头解释就能接上。
|
|
953
|
+
只有带着一份已签收回执的任务才会被列为 Done;pass_with_risk / pending /
|
|
954
|
+
未经验证的工作会归到 Unverified 之下。这份草稿是一个供你复核并补全的起点,不是一份已完成的交接。
|
|
955
|
+
ai-collab capability detect [--project <dir>] [--tools <list>] [--families <list>] [--subagents] [--can-switch-model] [--can-rerun] [--no-new-conversation] [--json]
|
|
956
|
+
|
|
957
|
+
bootstrap:你的 AI 用来给你做 onboarding 的扫描引擎。第一次协作时,你的 AI
|
|
958
|
+
被指示跑它来查看你最近的工作(是否真跑取决于你的工具有没有加载这条规则——见 first-run);你也可以随时自己运行它,
|
|
959
|
+
得到一份只读基线。它读取你自己最近的工作——
|
|
960
|
+
你的仓库结构、你最近的 git 历史(只读)、你的 .aict 账本,以及
|
|
961
|
+
你的 AI 指令文件——并打印一份朴素的「AI 协作基线」,含
|
|
962
|
+
五张卡:PROFILE CLUES(画像线索——来自你配置的信号,比如
|
|
963
|
+
检测到的工具、最近改动的文件类型——是交给你自己 AI 去跟你确认的线索,
|
|
964
|
+
不是 bootstrap 下的结论),VERIFY(哪些『完成』暂时还不能信——待定的、风险尚未
|
|
965
|
+
签字的,或自报的跨族复核——按与 status/handoff 相同的诚实
|
|
966
|
+
规则重新计算,绝不被显示为已完成),RESUME(你进行中的任务、一份
|
|
967
|
+
缺失的交接、你反复改动的文件),ROLES(把你工作里扫到的高风险关键词
|
|
968
|
+
映射到已有的协助角色,比如 red-team / dual-guard——它只陈述「出现了风险词」
|
|
969
|
+
这个事实、是否真的适用由你的 AI 确认,绝不下风险判定),以及 HARVEST(你可以带走的
|
|
970
|
+
已确认心得)。它是确定性的、
|
|
971
|
+
本地的:不调用外部模型、不做猜测,
|
|
972
|
+
没有任何东西离开你的机器,而且它什么都不写(只读报告)。它会先
|
|
973
|
+
打印扫描范围并需要 --yes 才继续(--yes 为脚本场景跳过那次确认)。
|
|
974
|
+
一个空的/仅有示例的工作区会诚实地说「你还没有属于自己的数据」。
|
|
975
|
+
可选、默认关闭:--dialogue <路径> / --logs <路径> 只读取你自己指定的
|
|
976
|
+
本地对话/日志导出(多个用逗号分隔),并加入确定性、已去敏的发现——
|
|
977
|
+
账本无法支撑的聊天「完成」会被列为「来自对话的声明 · 未验证」(绝不显示成
|
|
978
|
+
已完成),你反复做出的纠正会成为一个「候选」profile(不保存任何东西)。
|
|
979
|
+
仍然本地、仍然不调模型、仍然不联网。
|
|
980
|
+
|
|
981
|
+
守卫等级(L0-L4)评定一个『完成』背后的证据,并据此为它所能挣得的判定封顶。
|
|
982
|
+
一句话:更多/更独立的证据 -> 更高的等级 -> 更强的通过;单一
|
|
983
|
+
工具最高只到 L2(pass_with_risk),而一个干净的『pass』需要一次 L3+ 的跨族复核。
|
|
984
|
+
等级由 CLI 根据你的证据计算得出——你从不声明它(--claimed-level,
|
|
985
|
+
即旧的 --guard-level,只在你声明的等级超过证据所能支撑时发出警告)。
|
|
986
|
+
完整的 L0-L4 阶梯、每个等级如何挣得,以及家族诚实方面的限定,请运行:
|
|
987
|
+
node bin/ai-collab.js --help levels
|
|
988
|
+
一份 pass_with_risk 回执被创建为「pending」,需要 "receipt accept --owner [name]" 才能被签收。
|
|
989
|
+
Owner 签收记录的是一次本地的人类签字(行为人 + 时间戳)——一条协作审计轨迹,而非密码学签名。
|
|
990
|
+
|
|
991
|
+
Capability detect:与一份回执的守卫等级是不同的问题。回执说的是这个任务挣得了什么;
|
|
992
|
+
"capability detect" 说的是你的配置最高可能拿到多少分——你的天花板。它探测项目里的工具
|
|
993
|
+
标记(.claude/、.codex/、.cursor/、AGENTS.md…),并接收自报标志(--tools / --families /
|
|
994
|
+
--subagents / --can-switch-model / --can-rerun),因为 CLI 看不见你装了哪个 AI。
|
|
995
|
+
起决定作用的裁判是你能带来的不同模型家族的数量,而非工具数量:两个同族
|
|
996
|
+
工具共享盲点(仍是 L2);第二个、不同的家族才是通往干净通过(L3)的门槛;在此之上你自己
|
|
997
|
+
再把命令重跑一遍才到 L4。然后它会打印出抬高天花板最有价值的那一步。
|
|
998
|
+
天花板不等于已达成:天花板是你的工具最多能支撑到的程度;每个任务仍然要用它所引用的
|
|
999
|
+
证据去挣得自己的等级。项目信号是推断,不是证明(一个标记文件并不能锁定一个模型家族),
|
|
1000
|
+
所以请用 --tools / --families 来确认。
|
|
1001
|
+
|
|
1002
|
+
学习账本:记下一个任务教会你的东西,好让下一个任务起步更靠前。"learning add" 提出一条
|
|
1003
|
+
心得(--type harvest)或一条长期偏好(--type profile);它落为「proposed」直到你保留它
|
|
1004
|
+
(learning confirm)、改写并保留它(learning edit),或丢弃它(learning drop)。只有已确认/已改写的
|
|
1005
|
+
行才会毕业进入你的长期画像——没有任何东西仅凭 AI 一面之词就生效。每个任务最多保留一条 harvest +
|
|
1006
|
+
一条 profile。然后 "status" 会回显你最近确认的那一条偏好,让你感觉这个
|
|
1007
|
+
工具在学习你怎么工作,而你无需维护一套系统。
|
|
1008
|
+
|
|
1009
|
+
--tool 选择哪些 AI 工具会拿到一个指令文件。取值:cursor、codex、
|
|
1010
|
+
claude、copilot、cline、windsurf、all、auto(多个用逗号分隔)。
|
|
1011
|
+
默认 auto 只为在目标里检测到的工具安装;若一个都没检测到,
|
|
1012
|
+
它什么都不写并要求你传 --tool。用 --tool all 安装全部六个。
|
|
1013
|
+
|
|
1014
|
+
三个适配档位,从最不侵入到最侵入:
|
|
1015
|
+
1. rules (默认,永远安全)-- --tool 写入的每工具指令文件。
|
|
1016
|
+
2. skills(可选) -- .aict/skills/ 里可复用的能力卡
|
|
1017
|
+
(由 init 创建),按需加载进一个工具。
|
|
1018
|
+
3. hooks (可选,默认关闭)-- --enable-hooks 添加一个仅限本项目的 Claude
|
|
1019
|
+
Code Stop 钩子,在出现完成声明时提醒你
|
|
1020
|
+
记录一份回执。绝不是全局钩子;安装时会先
|
|
1021
|
+
列出每个文件,且可移除。只对 --tool claude 生效。
|
|
1022
|
+
|
|
1023
|
+
首次体验(推荐):
|
|
1024
|
+
init -> 打开 .aict/walkthroughs/10-minute-your-task.md -> 在你自己的一个真实任务上跑完整一圈
|
|
1025
|
+
(想先在一个预置示例上看看流程?改为打开 .aict/walkthroughs/10-minute.md)
|
|
1026
|
+
|
|
1027
|
+
立即运行(发布前):
|
|
1028
|
+
node bin/ai-collab.js init --dry-run # 仅预览,不写入任何东西
|
|
1029
|
+
node bin/ai-collab.js init --target ./my-ai-workspace # 写出工作区
|
|
1030
|
+
|
|
1031
|
+
网络:未使用。
|
|
1032
|
+
`
|
|
1033
|
+
}
|
|
1034
|
+
};
|