@inventarch/cli 0.0.0-stage → 1.0.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.
Files changed (110) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +4 -0
  3. package/README.md +19 -2
  4. package/SPEC.md +30 -0
  5. package/assets/base/71f0665cb1ffc3f3964fc7710528451f635d664bdf4b8c95005ee97c21db5928.ia.tgz +0 -0
  6. package/assets/base.json +6 -0
  7. package/assets/host/43a1f8c471141b1f2f46cef4411a9a61c00da1c1aa19d277189ae2423282bfd6.tgz +0 -0
  8. package/assets/host.json +6 -0
  9. package/assets/vocabulary.json +3268 -0
  10. package/dist/args.d.ts +62 -0
  11. package/dist/args.d.ts.map +1 -0
  12. package/dist/args.js +117 -0
  13. package/dist/args.js.map +1 -0
  14. package/dist/briefing.d.ts +76 -0
  15. package/dist/briefing.d.ts.map +1 -0
  16. package/dist/briefing.js +105 -0
  17. package/dist/briefing.js.map +1 -0
  18. package/dist/channel.d.ts +22 -0
  19. package/dist/channel.d.ts.map +1 -0
  20. package/dist/channel.js +74 -0
  21. package/dist/channel.js.map +1 -0
  22. package/dist/claude-cli.d.ts +35 -0
  23. package/dist/claude-cli.d.ts.map +1 -0
  24. package/dist/claude-cli.js +101 -0
  25. package/dist/claude-cli.js.map +1 -0
  26. package/dist/commands.d.ts +39 -0
  27. package/dist/commands.d.ts.map +1 -0
  28. package/dist/commands.js +436 -0
  29. package/dist/commands.js.map +1 -0
  30. package/dist/compile.d.ts +39 -0
  31. package/dist/compile.d.ts.map +1 -0
  32. package/dist/compile.js +136 -0
  33. package/dist/compile.js.map +1 -0
  34. package/dist/consumer.d.ts +137 -0
  35. package/dist/consumer.d.ts.map +1 -0
  36. package/dist/consumer.js +366 -0
  37. package/dist/consumer.js.map +1 -0
  38. package/dist/decline.d.ts +7 -0
  39. package/dist/decline.d.ts.map +1 -0
  40. package/dist/decline.js +78 -0
  41. package/dist/decline.js.map +1 -0
  42. package/dist/distribute.d.ts +163 -0
  43. package/dist/distribute.d.ts.map +1 -0
  44. package/dist/distribute.js +664 -0
  45. package/dist/distribute.js.map +1 -0
  46. package/dist/doctor-user.d.ts +45 -0
  47. package/dist/doctor-user.d.ts.map +1 -0
  48. package/dist/doctor-user.js +193 -0
  49. package/dist/doctor-user.js.map +1 -0
  50. package/dist/doctor.d.ts +57 -0
  51. package/dist/doctor.d.ts.map +1 -0
  52. package/dist/doctor.js +754 -0
  53. package/dist/doctor.js.map +1 -0
  54. package/dist/format.d.ts +25 -0
  55. package/dist/format.d.ts.map +1 -0
  56. package/dist/format.js +168 -0
  57. package/dist/format.js.map +1 -0
  58. package/dist/home-remedy.d.ts +10 -0
  59. package/dist/home-remedy.d.ts.map +1 -0
  60. package/dist/home-remedy.js +26 -0
  61. package/dist/home-remedy.js.map +1 -0
  62. package/dist/host-projection.d.ts +11 -0
  63. package/dist/host-projection.d.ts.map +1 -0
  64. package/dist/host-projection.js +73 -0
  65. package/dist/host-projection.js.map +1 -0
  66. package/dist/host.d.ts +162 -0
  67. package/dist/host.d.ts.map +1 -0
  68. package/dist/host.js +599 -0
  69. package/dist/host.js.map +1 -0
  70. package/dist/init.d.ts +217 -0
  71. package/dist/init.d.ts.map +1 -0
  72. package/dist/init.js +840 -0
  73. package/dist/init.js.map +1 -0
  74. package/dist/inspect.d.ts +32 -0
  75. package/dist/inspect.d.ts.map +1 -0
  76. package/dist/inspect.js +226 -0
  77. package/dist/inspect.js.map +1 -0
  78. package/dist/main.d.ts +24 -0
  79. package/dist/main.d.ts.map +1 -0
  80. package/dist/main.js +215 -0
  81. package/dist/main.js.map +1 -0
  82. package/dist/operation-help.d.ts +14 -0
  83. package/dist/operation-help.d.ts.map +1 -0
  84. package/dist/operation-help.js +75 -0
  85. package/dist/operation-help.js.map +1 -0
  86. package/dist/pack.d.ts +17 -0
  87. package/dist/pack.d.ts.map +1 -0
  88. package/dist/pack.js +121 -0
  89. package/dist/pack.js.map +1 -0
  90. package/dist/render.d.ts +165 -0
  91. package/dist/render.d.ts.map +1 -0
  92. package/dist/render.js +277 -0
  93. package/dist/render.js.map +1 -0
  94. package/dist/session.d.ts +13 -0
  95. package/dist/session.d.ts.map +1 -0
  96. package/dist/session.js +25 -0
  97. package/dist/session.js.map +1 -0
  98. package/dist/user-host.d.ts +59 -0
  99. package/dist/user-host.d.ts.map +1 -0
  100. package/dist/user-host.js +228 -0
  101. package/dist/user-host.js.map +1 -0
  102. package/dist/validate.d.ts +53 -0
  103. package/dist/validate.d.ts.map +1 -0
  104. package/dist/validate.js +220 -0
  105. package/dist/validate.js.map +1 -0
  106. package/dist/vocabulary.d.ts +55 -0
  107. package/dist/vocabulary.d.ts.map +1 -0
  108. package/dist/vocabulary.js +179 -0
  109. package/dist/vocabulary.js.map +1 -0
  110. package/package.json +153 -3
package/dist/args.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The consumer argument grammar: docs/specs/consumer-cli-contract/README.md §2.0.
3
+ *
4
+ * `--flag value` and `--flag=value`, boolean flags, a bare `--` separator, repeatable flags and repeatable
5
+ * positionals. A command declares its shape in a table and the parser enforces it, so no handler reads a flag
6
+ * name of its own. Every refusal here is IA-CLI-USAGE at exit 2 (§3) and happens before any workspace,
7
+ * installation state, cache or network read.
8
+ */
9
+ export declare class UsageError extends Error {
10
+ readonly code = "IA-CLI-USAGE";
11
+ constructor(message: string);
12
+ }
13
+ export interface OptionSpec {
14
+ readonly name: string;
15
+ readonly kind: 'boolean' | 'value';
16
+ /** One-letter alias, matched as an exact token; bundling such as `-qy` is not admitted. */
17
+ readonly short?: string;
18
+ readonly repeatable?: boolean;
19
+ /** A closed value set. A value outside it is a usage error, not a later refusal. */
20
+ readonly values?: readonly string[];
21
+ readonly integer?: {
22
+ readonly min: number;
23
+ readonly max?: number;
24
+ };
25
+ /** How the value is spelled in help; defaults to the value set, or `<value>`. */
26
+ readonly placeholder?: string;
27
+ readonly required?: boolean;
28
+ /** Names that may not appear alongside this one, in either order. */
29
+ readonly conflicts?: readonly string[];
30
+ /** §2.2: `--schema` and `--example` are meaningless without the word they describe. */
31
+ readonly needsPositional?: boolean;
32
+ /** §2.8: `--requests` carries the set the positionals would have carried. */
33
+ readonly excludesPositionals?: boolean;
34
+ /** §2.1 rejects the common `--root` for `ia init`; the reason is stated rather than spelled as "unknown". */
35
+ readonly refuse?: string;
36
+ readonly summary: string;
37
+ }
38
+ export interface PositionalSpec {
39
+ readonly name: string;
40
+ readonly min: number;
41
+ /** `Number.POSITIVE_INFINITY` for a repeatable positional. */
42
+ readonly max: number;
43
+ }
44
+ export interface Grammar {
45
+ readonly options: readonly OptionSpec[];
46
+ readonly positionals: PositionalSpec;
47
+ }
48
+ export interface Arguments {
49
+ readonly positionals: readonly string[];
50
+ /** True when the boolean flag was supplied. */
51
+ readonly flag: (name: string) => boolean;
52
+ /** The single value of a non-repeatable value flag. */
53
+ readonly value: (name: string) => string | undefined;
54
+ /** Every occurrence of a repeatable value flag, in the order supplied. */
55
+ readonly list: (name: string) => readonly string[];
56
+ readonly integer: (name: string, fallback: number) => number;
57
+ }
58
+ export declare const positionals: (name: string, min: number, max: number) => PositionalSpec;
59
+ export declare const none: PositionalSpec;
60
+ /** §2.0. Pure: the same argv and grammar always produce the same result or the same refusal. */
61
+ export declare function parseArguments(argv: readonly string[], grammar: Grammar): Arguments;
62
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,kBAAkB;gBACnB,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IACnC,2FAA2F;IAC3F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,oFAAoF;IACpF,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,iFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,uFAAuF;IACvF,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,6GAA6G;IAC7G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AACD,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;CACtC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACrD,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CAC9D;AAGD,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,cAAsC,CAAC;AAC5G,eAAO,MAAM,IAAI,gBAAiB,CAAC;AAInC,gGAAgG;AAChG,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CA+FnF"}
package/dist/args.js ADDED
@@ -0,0 +1,117 @@
1
+ /**
2
+ * The consumer argument grammar: docs/specs/consumer-cli-contract/README.md §2.0.
3
+ *
4
+ * `--flag value` and `--flag=value`, boolean flags, a bare `--` separator, repeatable flags and repeatable
5
+ * positionals. A command declares its shape in a table and the parser enforces it, so no handler reads a flag
6
+ * name of its own. Every refusal here is IA-CLI-USAGE at exit 2 (§3) and happens before any workspace,
7
+ * installation state, cache or network read.
8
+ */
9
+ export class UsageError extends Error {
10
+ code = 'IA-CLI-USAGE';
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = 'UsageError';
14
+ }
15
+ }
16
+ const NO_POSITIONALS = { name: 'argument', min: 0, max: 0 };
17
+ export const positionals = (name, min, max) => ({ name, min, max });
18
+ export const none = NO_POSITIONALS;
19
+ const label = (option) => `--${option.name}`;
20
+ /** §2.0. Pure: the same argv and grammar always produce the same result or the same refusal. */
21
+ export function parseArguments(argv, grammar) {
22
+ const byToken = new Map();
23
+ for (const option of grammar.options) {
24
+ byToken.set(`--${option.name}`, option);
25
+ if (option.short !== undefined)
26
+ byToken.set(`-${option.short}`, option);
27
+ }
28
+ const values = new Map(), flags = new Set(), rest = [];
29
+ let separated = false;
30
+ for (let index = 0; index < argv.length; index += 1) {
31
+ const token = argv[index];
32
+ if (!separated && token === '--') {
33
+ separated = true;
34
+ continue;
35
+ }
36
+ if (separated || !token.startsWith('-') || token === '-') {
37
+ rest.push(token);
38
+ continue;
39
+ }
40
+ const split = token.indexOf('='), key = split === -1 ? token : token.slice(0, split);
41
+ const option = byToken.get(key);
42
+ if (option === undefined)
43
+ throw new UsageError(`Unknown option ${key}`);
44
+ if (option.refuse !== undefined)
45
+ throw new UsageError(option.refuse);
46
+ if (option.kind === 'boolean') {
47
+ if (split !== -1)
48
+ throw new UsageError(`Option ${label(option)} does not take a value`);
49
+ if (flags.has(option.name))
50
+ throw new UsageError(`Duplicate option ${label(option)}`);
51
+ flags.add(option.name);
52
+ continue;
53
+ }
54
+ // A separate token is taken as the value unless it is itself a declared option, so `--search -x` works and
55
+ // `--severity --json` refuses instead of silently swallowing the next flag. `--flag=value` escapes both.
56
+ const next = argv[index + 1];
57
+ const supplied = split === -1 ? (next !== undefined && byToken.has(next) ? undefined : next) : token.slice(split + 1);
58
+ if (supplied === undefined || supplied === '')
59
+ throw new UsageError(`Option ${label(option)} requires a value`);
60
+ if (split === -1)
61
+ index += 1;
62
+ const seen = values.get(option.name);
63
+ if (seen !== undefined && option.repeatable !== true)
64
+ throw new UsageError(`Duplicate option ${label(option)}`);
65
+ if (seen === undefined)
66
+ values.set(option.name, [supplied]);
67
+ else
68
+ seen.push(supplied);
69
+ }
70
+ for (const option of grammar.options) {
71
+ const present = option.kind === 'boolean' ? flags.has(option.name) : values.has(option.name);
72
+ if (!present) {
73
+ if (option.required === true)
74
+ throw new UsageError(`Option ${label(option)} is required`);
75
+ continue;
76
+ }
77
+ for (const other of option.conflicts ?? []) {
78
+ const conflicting = flags.has(other) || values.has(other);
79
+ if (conflicting)
80
+ throw new UsageError(`Options ${label(option)} and --${other} are mutually exclusive`);
81
+ }
82
+ if (option.needsPositional === true && rest.length === 0)
83
+ throw new UsageError(`Option ${label(option)} requires <${grammar.positionals.name}>`);
84
+ if (option.excludesPositionals === true && rest.length > 0)
85
+ throw new UsageError(`Option ${label(option)} and <${grammar.positionals.name}> are mutually exclusive`);
86
+ for (const value of values.get(option.name) ?? []) {
87
+ if (option.values !== undefined && !option.values.includes(value))
88
+ throw new UsageError(`Option ${label(option)} accepts ${option.values.join(', ')}; got ${value}`);
89
+ if (option.integer !== undefined) {
90
+ const parsed = Number(value), { min, max } = option.integer;
91
+ if (!/^-?\d+$/.test(value) ||
92
+ !Number.isSafeInteger(parsed) ||
93
+ parsed < min ||
94
+ (max !== undefined && parsed > max))
95
+ throw new UsageError(`Option ${label(option)} accepts an integer ${max === undefined ? `of at least ${min}` : `from ${min} to ${max}`}; got ${value}`);
96
+ }
97
+ }
98
+ }
99
+ const spec = grammar.positionals;
100
+ if (rest.length > spec.max)
101
+ throw new UsageError(spec.max === 0
102
+ ? `Unexpected argument ${rest[0]}`
103
+ : `Expected at most ${spec.max} <${spec.name}>; got ${rest.length}`);
104
+ if (rest.length < spec.min)
105
+ throw new UsageError(`Expected <${spec.name}>`);
106
+ return {
107
+ positionals: rest,
108
+ flag: (name) => flags.has(name),
109
+ value: (name) => values.get(name)?.[0],
110
+ list: (name) => values.get(name) ?? [],
111
+ integer: (name, fallback) => {
112
+ const raw = values.get(name)?.[0];
113
+ return raw === undefined ? fallback : Number(raw);
114
+ },
115
+ };
116
+ }
117
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * docs/specs/host-plugin-distribution/README.md §8.2: what the session hook tells the model and the user.
3
+ * A pure function of facts `ia doctor` already gathered, so every row of §8.2 is a unit test. At most one notice:
4
+ * version skew, then an interrupted installation or a stale or missing host, then a decline reminder, then an update.
5
+ * Dates are the user's local calendar date, as the `declined-today` expiry is (§9.1).
6
+ *
7
+ * `nextActions` is §7.3's `[{intent, argv, host}]`: `host` is the adapter row's own invocation where §4's table
8
+ * declares one (Claude's `/ia:init`), otherwise the plain command. The Claude plugin is a Claude concern, so its version
9
+ * skew is reported only to a host whose row installs a plugin; a host with no workspace set (§4, Cursor) is never told
10
+ * its registration is missing, because `ia host` would refuse to write one. When doctor could not observe the host set
11
+ * (an interrupted installation, or installed state it could not read) the briefing says so, for every host, and never
12
+ * suggests `ia host`, which would refuse until recovery runs.
13
+ *
14
+ * One report has one root. Given `--root`, doctor reports that directory literally, so every command the briefing
15
+ * names carries it the way its verb takes a directory: `ia host <host> --root <root>`, and `ia init <root>` (init takes
16
+ * its target as a positional and refuses `--root`). A host's own invocation runs in the session's project directory,
17
+ * so it is used only without `--root`. `ia host <host> --user` belongs to no workspace and refuses `--root`, so it
18
+ * never carries one. A supplied directory that is not itself a workspace but lies inside one is neither offered
19
+ * initialization nor described: the briefing names the enclosing workspace and the command that reports it.
20
+ */
21
+ import type { Decision } from '@inventarch/distribution/decisions';
22
+ import type { Intent } from '@inventarch/distribution/hosts';
23
+ import type { Channel } from './channel.js';
24
+ export interface NextAction {
25
+ readonly intent: Intent;
26
+ readonly argv: readonly string[];
27
+ /** The host's own invocation when its adapter row declares one and no --root was given; otherwise the plain command. */
28
+ readonly host: string;
29
+ }
30
+ export interface Session {
31
+ /** Lines for the model (§8.1 step 3's `additionalContext`). */
32
+ readonly context: readonly string[];
33
+ /** The one line the user sees, or null in the §8.2 states where the user sees nothing. */
34
+ readonly notice: string | null;
35
+ /** 'update' when the notice is an update nudge, which the hook shows at most once per local day (Amendment item 4). */
36
+ readonly nudge: 'update' | null;
37
+ /** The argument vector the hook starts detached to refresh the update cache, or null when none is due (Amendment item 4). */
38
+ readonly refresh: readonly string[] | null;
39
+ }
40
+ export interface BriefInput {
41
+ readonly host: string;
42
+ readonly version: string;
43
+ readonly channel: Channel;
44
+ /** The CLI version the materialized Claude plugin records, or null when it is absent or unreadable. */
45
+ readonly plugin: {
46
+ readonly cli: string;
47
+ } | null;
48
+ /** The workspace root, or undefined when there is no workspace. */
49
+ readonly root: string | undefined;
50
+ /** The `--root` doctor was given, or undefined when it discovered the root from the working directory. */
51
+ readonly supplied: string | undefined;
52
+ /** The workspace a supplied non-workspace directory lies inside, or null. */
53
+ readonly enclosing: string | null;
54
+ readonly frameworkSource: boolean;
55
+ readonly decision: Decision | null;
56
+ /** The records row's detail, or null when records were not read. */
57
+ readonly records: string | null;
58
+ /** 'unknown' when doctor could not observe the host set; 'absent' only when it observed none for this host. */
59
+ readonly hostStatus: 'registered' | 'stale' | 'absent' | 'unknown';
60
+ /** Why the host is stale, or why it was not observed: the failing rows' details, for the model. */
61
+ readonly hostDetail: string | null;
62
+ /** The pending row's remedy when an interrupted installation needs recovery, else null. */
63
+ readonly recovery: string | null;
64
+ readonly updates: {
65
+ readonly latest: string | null;
66
+ readonly behind: number | null;
67
+ } | null;
68
+ readonly refresh: readonly string[] | null;
69
+ }
70
+ /** A timestamp as the user's local calendar date, YYYY-MM-DD. */
71
+ export declare const localDate: (at: string) => string;
72
+ export declare function brief(input: BriefInput): {
73
+ readonly session: Session;
74
+ readonly nextActions: readonly NextAction[];
75
+ };
76
+ //# sourceMappingURL=briefing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"briefing.d.ts","sourceRoot":"","sources":["../src/briefing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAE7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,wHAAwH;IACxH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AACD,MAAM,WAAW,OAAO;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,uHAAuH;IACvH,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IAChC,6HAA6H;IAC7H,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CAC5C;AACD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uGAAuG;IACvG,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,0GAA0G;IAC1G,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,+GAA+G;IAC/G,QAAQ,CAAC,UAAU,EAAE,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IACnE,mGAAmG;IACnG,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5F,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CAC5C;AAQD,iEAAiE;AACjE,eAAO,MAAM,SAAS,GAAI,IAAI,MAAM,KAAG,MAAkD,CAAC;AAE1F,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,CAgGnH"}
@@ -0,0 +1,105 @@
1
+ import { hostRow, invocation, workspaceRow } from '@inventarch/distribution/hosts';
2
+ import { describeChannel, updateInstruction } from './channel.js';
3
+ import { quote } from './render.js';
4
+ /** An argument vector as one printable command, each argument quoted the way doctor's rows quote a root. */
5
+ const command = (argv) => argv.map(quote).join(' ');
6
+ /**
7
+ * The host as every notice and context line names it: `Claude`, `Codex`, `Cursor`. The adapter row's label is the
8
+ * product name ("Claude Code"); these lines name the host the way §8.2's own wording does.
9
+ */
10
+ const named = (host) => host.charAt(0).toUpperCase() + host.slice(1);
11
+ /** A timestamp as the user's local calendar date, YYYY-MM-DD. */
12
+ export const localDate = (at) => new Date(at).toLocaleDateString('en-CA');
13
+ export function brief(input) {
14
+ const context = [`ia ${input.version} (${describeChannel(input.channel)}).`];
15
+ const actions = [];
16
+ const rooted = input.supplied !== undefined;
17
+ const action = (intent, argv) => ({
18
+ intent,
19
+ argv,
20
+ host: rooted ? command(argv) : invocation(input.host, intent, argv),
21
+ });
22
+ let notice = null, nudge = null;
23
+ const first = (text) => {
24
+ if (notice === null)
25
+ notice = text;
26
+ };
27
+ // §8.2 row 2: the plugin the user runs was rendered by another ia; re-rendering it is the whole remedy.
28
+ if (hostRow(input.host)?.user === 'plugin' && input.plugin !== null && input.plugin.cli !== input.version) {
29
+ const user = ['ia', 'host', input.host, '--user', '--apply'];
30
+ first(`IA: the plugin was installed by ia ${input.plugin.cli} but ia is ${input.version}; run ${command(user)}`);
31
+ context.push(`The ${named(input.host)} plugin was installed by ia ${input.plugin.cli}; this is ia ${input.version}. Run ${command(user)}.`);
32
+ actions.push(action('host-user', user));
33
+ }
34
+ if (input.frameworkSource) {
35
+ context.push(`This is the InventArch framework source (${input.root}). Use its CLAUDE.md and pnpm gates; consumer workspace advice does not apply here.`);
36
+ }
37
+ else if (input.root === undefined && input.enclosing !== null) {
38
+ // The report is about the supplied directory, not the workspace above it; name that workspace and stop.
39
+ context.push(`${input.supplied} is inside InventArch workspace ${input.enclosing}; run ${command(['ia', 'doctor', '--root', input.enclosing])} for its state.`);
40
+ }
41
+ else if (input.root === undefined) {
42
+ const decision = input.decision;
43
+ if (decision?.decision === 'declined-forever') {
44
+ const on = localDate(decision.at);
45
+ first(`IA not installed in ${decision.path}; declined by user ${on}`);
46
+ context.push(`The user declined InventArch here permanently on ${on}. Do not offer initialization. "ia init" still works if the user asks for it explicitly.`);
47
+ }
48
+ else if (decision?.decision === 'declined-today') {
49
+ context.push('The user declined initialization here today. Do not offer it again.');
50
+ }
51
+ else {
52
+ // §8.3: an instruction to the model, not a mechanical guarantee.
53
+ const init = action('init', ['ia', 'init', input.supplied ?? '.']);
54
+ context.push(`${rooted ? `${input.supplied} is` : 'This directory is'} not an InventArch workspace. Do not search the filesystem for other .ia trees or IA tooling. Offer initialization only if the user's request involves InventArch, .ia records or their governance; then use ${init.host === command(init.argv) ? `"${init.host}"` : init.host}.`);
55
+ actions.push(init);
56
+ }
57
+ }
58
+ else {
59
+ context.push(`InventArch workspace ${input.root}: ${input.records ?? 'records not read'}.`);
60
+ const label = named(input.host);
61
+ const apply = [
62
+ 'ia',
63
+ 'host',
64
+ input.host,
65
+ ...(input.supplied === undefined ? [] : ['--root', input.supplied]),
66
+ '--apply',
67
+ ];
68
+ if (input.hostStatus === 'unknown') {
69
+ // Every ia host plan refuses until recovery runs, so recovery is the only command worth naming, for any host.
70
+ if (input.recovery !== null)
71
+ first(`IA: an interrupted installation needs recovery; run ${input.recovery}`);
72
+ context.push(`Host ${label}: not checked${input.hostDetail === null ? '' : ` (${input.hostDetail})`}.${input.recovery === null ? '' : ` An interrupted installation needs recovery first: ${input.recovery}.`} Do not run ia host until ia doctor reports the host set.`);
73
+ }
74
+ else if (workspaceRow(input.host) === undefined)
75
+ context.push(`Host ${label} has no workspace registration in this ia.`);
76
+ else if (input.hostStatus === 'registered')
77
+ context.push(`Host ${label}: registered.`);
78
+ else {
79
+ if (input.hostStatus === 'stale') {
80
+ first(`IA: the ${label} host registration for this workspace is stale; run ${command(apply)}`);
81
+ context.push(`Host ${label}: stale${input.hostDetail === null ? '' : ` — ${input.hostDetail}`}. Run ${command(apply)}.`);
82
+ }
83
+ else {
84
+ first(`IA: this workspace has no ${label} host registration; run ${command(apply)}`);
85
+ context.push(`Host ${label}: not registered. Run ${command(apply)}.`);
86
+ }
87
+ actions.push(action('host', apply));
88
+ }
89
+ }
90
+ // §8.2 last row and §11: only from the cache doctor already read; the hook, not doctor, limits it to once a day.
91
+ const updates = input.updates;
92
+ const newer = updates !== null && updates.latest !== null && updates.latest !== input.version;
93
+ if (updates !== null && (newer || (updates.behind ?? 0) > 0)) {
94
+ const what = newer
95
+ ? `ia ${updates.latest} is available (you have ${input.version})`
96
+ : `your checkout is ${updates.behind} commits behind its upstream`;
97
+ context.push(`Update: ${what}. ${updateInstruction(input.channel)}.`);
98
+ if (notice === null) {
99
+ notice = `IA: ${what}. ${updateInstruction(input.channel)}`;
100
+ nudge = 'update';
101
+ }
102
+ }
103
+ return { session: { context, notice, nudge, refresh: input.refresh }, nextActions: actions };
104
+ }
105
+ //# sourceMappingURL=briefing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"briefing.js","sourceRoot":"","sources":["../src/briefing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export type Channel = {
2
+ readonly kind: 'checkout';
3
+ readonly root: string;
4
+ readonly commit: string | null;
5
+ readonly dirty: boolean | null;
6
+ readonly origin: string | null;
7
+ } | {
8
+ readonly kind: 'npm';
9
+ readonly name: string;
10
+ readonly version: string;
11
+ } | {
12
+ readonly kind: 'unknown';
13
+ readonly entry: string;
14
+ };
15
+ export type Git = (cwd: string, args: readonly string[]) => string | null;
16
+ export declare const runGit: Git;
17
+ /** §5's table, top to bottom: under node_modules is npm; inside this repository's own work tree is a checkout. */
18
+ export declare function detectChannel(packageRoot: string, git?: Git): Channel;
19
+ /** §5's update instruction for the channel, as the hook and doctor print it. */
20
+ export declare function updateInstruction(channel: Channel): string;
21
+ export declare function describeChannel(channel: Channel): string;
22
+ //# sourceMappingURL=channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,OAAO,GACf;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACzD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI,CAAC;AAC1E,eAAO,MAAM,MAAM,EAAE,GAUpB,CAAC;AASF,kHAAkH;AAClH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,GAAY,GAAG,OAAO,CA8B7E;AACD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAK1D;AACD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAKxD"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Host plugin distribution spec §5: how this installation of `ia` is running, read from where its package sits.
3
+ * Only the filesystem and local git are consulted; nothing here touches the network.
4
+ */
5
+ import { spawnSync } from 'node:child_process';
6
+ import { existsSync, readFileSync, realpathSync } from 'node:fs';
7
+ import { dirname, resolve, sep } from 'node:path';
8
+ import { sameFile } from '@inventarch/db';
9
+ export const runGit = (cwd, args) => {
10
+ // --no-optional-locks: doctor calls this on every session start, and it must never contend with a concurrent
11
+ // git process for the index lock. 700ms each: three sequential calls (rev-parse, status, config) must leave
12
+ // headroom inside the hook's 5s doctor budget for workspace validation.
13
+ const result = spawnSync('git', ['--no-optional-locks', '-C', cwd, ...args], {
14
+ encoding: 'utf8',
15
+ timeout: 700,
16
+ windowsHide: true,
17
+ });
18
+ return result.status === 0 ? result.stdout.trim() : null;
19
+ };
20
+ const real = (path) => {
21
+ try {
22
+ return realpathSync(path);
23
+ }
24
+ catch {
25
+ return resolve(path);
26
+ }
27
+ };
28
+ /** §5's table, top to bottom: under node_modules is npm; inside this repository's own work tree is a checkout. */
29
+ export function detectChannel(packageRoot, git = runGit) {
30
+ const root = real(packageRoot);
31
+ if (root.split(sep).includes('node_modules')) {
32
+ try {
33
+ const manifest = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8'));
34
+ return { kind: 'npm', name: manifest.name ?? 'unknown', version: manifest.version ?? '0.0.0' };
35
+ }
36
+ catch {
37
+ return { kind: 'unknown', entry: resolve(root, 'dist/main.js') };
38
+ }
39
+ }
40
+ for (let current = root;; current = dirname(current)) {
41
+ if (existsSync(resolve(current, '.git'))) {
42
+ if (existsSync(resolve(current, 'pnpm-workspace.yaml')) && sameFile(resolve(current, 'apps/cli'), root)) {
43
+ const status = git(current, ['status', '--porcelain', '--untracked-files=no']);
44
+ return {
45
+ kind: 'checkout',
46
+ root: current,
47
+ commit: git(current, ['rev-parse', 'HEAD']),
48
+ dirty: status === null ? null : status !== '',
49
+ origin: git(current, ['config', '--get', 'remote.origin.url']),
50
+ };
51
+ }
52
+ break;
53
+ }
54
+ if (dirname(current) === current)
55
+ break;
56
+ }
57
+ return { kind: 'unknown', entry: resolve(root, 'dist/main.js') };
58
+ }
59
+ /** §5's update instruction for the channel, as the hook and doctor print it. */
60
+ export function updateInstruction(channel) {
61
+ if (channel.kind === 'checkout')
62
+ return `In ${channel.root}: git pull, pnpm build, then ia host claude --user --apply`;
63
+ if (channel.kind === 'npm')
64
+ return `npm i -g ${channel.name}@latest, then ia host claude --user --apply`;
65
+ return 'Reinstall ia from its source, then run ia host claude --user --apply';
66
+ }
67
+ export function describeChannel(channel) {
68
+ if (channel.kind === 'checkout')
69
+ return `checkout ${channel.root}${channel.commit ? ` at ${channel.commit.slice(0, 12)}` : ''}${channel.dirty === true ? ', uncommitted changes' : channel.dirty === null ? ', dirty state unknown' : ''}${channel.origin ? `, origin ${channel.origin}` : ''}`;
70
+ if (channel.kind === 'npm')
71
+ return `npm package ${channel.name} ${channel.version}`;
72
+ return `unknown install; running from ${channel.entry}`;
73
+ }
74
+ //# sourceMappingURL=channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { SpawnSyncReturns } from 'node:child_process';
2
+ type Env = Readonly<Record<string, string | undefined>>;
3
+ export declare const PLUGIN_ID = "ia@inventarch";
4
+ /** null: not known, because claude is unavailable or its list did not parse. */
5
+ export interface ClaudeState {
6
+ readonly marketplaceKnown: boolean | null;
7
+ readonly installed: boolean | null;
8
+ }
9
+ export interface ClaudeRunner {
10
+ readonly available: boolean;
11
+ /** `stdout` alone is what a `--json` list is parsed from; `output` is both streams, for a refusal to quote. */
12
+ readonly run: (args: readonly string[]) => {
13
+ readonly status: number | null;
14
+ readonly stdout: string;
15
+ readonly output: string;
16
+ };
17
+ }
18
+ /**
19
+ * §2.3's observed shapes: `plugin marketplace list --json` is an array of `{name, …}` and `plugin list --json` an
20
+ * array of `{id, scope, …}`. Only a user-scope install is ours to remove; a row without a scope is taken as one.
21
+ */
22
+ export declare function observeClaude(runner: ClaudeRunner): ClaudeState;
23
+ /** §2.3: `marketplace add` and `install` are both idempotent, so registration is always the same two commands. */
24
+ export declare const registrationCommands: (marketplace: string) => string[][];
25
+ /** §2.3: `uninstall` and `remove` exit 1 when there is nothing to remove, so only what is listed (or unknown) is removed. */
26
+ export declare function removalCommands(state: ClaudeState): string[][];
27
+ export type Spawn = (command: string, args: readonly string[], options: Readonly<Record<string, unknown>>) => SpawnSyncReturns<string>;
28
+ /** Injected only by tests, which exercise the Windows resolution without running a real `claude`. */
29
+ export interface RunnerDependencies {
30
+ readonly platform: NodeJS.Platform;
31
+ readonly spawn: Spawn;
32
+ }
33
+ export declare function claudeRunner(env: Env, dependencies?: RunnerDependencies): ClaudeRunner;
34
+ export {};
35
+ //# sourceMappingURL=claude-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-cli.d.ts","sourceRoot":"","sources":["../src/claude-cli.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAK3D,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AACxD,eAAO,MAAM,SAAS,kBAA2C,CAAC;AAClE,gFAAgF;AAChF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CACpC;AACD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,+GAA+G;IAC/G,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK;QACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAeD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW,CAc/D;AACD,kHAAkH;AAClH,eAAO,MAAM,oBAAoB,GAAI,aAAa,MAAM,KAAG,MAAM,EAAE,EAGlE,CAAC;AACF,6HAA6H;AAC7H,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,EAAE,EAAE,CAK9D;AAOD,MAAM,MAAM,KAAK,GAAG,CAClB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KACvC,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC9B,qGAAqG;AACrG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAoBD,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,GAAE,kBAA6B,GAAG,YAAY,CAgChG"}