xcoder-dna 1.3.0 → 1.4.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/LICENSE CHANGED
@@ -1,66 +1,21 @@
1
- Copyright (c) 2026 Sir John M. Nueva
2
- All Rights Reserved.
3
-
4
- PROPRIETARY AND CONFIDENTIAL
5
-
6
- This repository and all of its contents — including but not limited to source code,
7
- documentation, system designs, component contracts, methodology specifications,
8
- blueprints, templates, diagrams, data schemas, configuration files, and all other
9
- associated materials (collectively, the "Work") — are the exclusive intellectual
10
- property of Sir John M. Nueva.
11
-
12
- RESTRICTIONS
13
-
14
- No part of the Work may, without the prior explicit written permission of
15
- Sir John M. Nueva:
16
-
17
- 1. Be reproduced, copied, or duplicated in any form or by any means,
18
- electronic or mechanical.
19
-
20
- 2. Be modified, adapted, translated, or used to create derivative works.
21
-
22
- 3. Be distributed, published, transmitted, sold, sublicensed, or otherwise
23
- made available to any third party.
24
-
25
- 4. Be used for commercial, educational, research, or any other purpose,
26
- whether for profit or not.
27
-
28
- 5. Be reverse-engineered, decompiled, or disassembled.
29
-
30
- OWNERSHIP
31
-
32
- The Work is protected under applicable copyright laws and international
33
- treaty provisions. Sir John M. Nueva retains all intellectual property rights,
34
- title, and interest in and to the Work, including all copies, modifications,
35
- and derivative works thereof, regardless of the form in which they exist.
36
-
37
- NO LICENSE GRANTED
38
-
39
- Nothing in this repository constitutes a grant — express, implied, or by
40
- estoppel — of any license, right, or permission to use, copy, modify,
41
- distribute, or otherwise exploit the Work or any portion thereof.
42
-
43
- NO WARRANTY
44
-
45
- THE WORK IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
- FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. IN NO EVENT SHALL
48
- SIR JOHN M. NUEVA BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY,
49
- WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF,
50
- OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS IN THE WORK.
51
-
52
- ENFORCEMENT
53
-
54
- Any unauthorized use, reproduction, distribution, or modification of the Work
55
- constitutes copyright infringement and may result in civil and criminal penalties
56
- to the maximum extent permitted by applicable law.
57
-
58
- CONTACT
59
-
60
- For licensing inquiries or written permission requests, contact:
61
-
62
- Sir John M. Nueva
63
-
64
- -------------------------------------------------------------------------------
65
- Copyright (c) 2026 Sir John M. Nueva. All Rights Reserved.
66
- -------------------------------------------------------------------------------
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Neural Node Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,90 @@
1
+ import type { Command } from "commander";
2
+ /** The closed allowlist of agent CLIs that may be reached through `xcoder`. */
3
+ export declare const DELEGABLE_TARGETS: readonly ["jarvis", "litebro", "bugfinder"];
4
+ export type DelegableTarget = (typeof DELEGABLE_TARGETS)[number];
5
+ /** Shell convention for "command not found", identical on every platform. */
6
+ export declare const EXIT_ENOENT = 127;
7
+ /**
8
+ * Interrupted. POSIX would be 128+SIGINT (130); Windows has no signal-number
9
+ * convention, so one deterministic, testable constant is used everywhere.
10
+ */
11
+ export declare const EXIT_INTERRUPTED = 130;
12
+ export interface DelegateSpec {
13
+ /** Allowlisted target name as typed by the user. */
14
+ readonly target: DelegableTarget;
15
+ /** Executable name on PATH, used when the workspace build is absent. */
16
+ readonly bin: string;
17
+ /** Workspace-relative built entry point, tried before PATH. */
18
+ readonly fallbackModule: string;
19
+ /** One-line description used in command help. */
20
+ readonly summary: string;
21
+ }
22
+ /** Minimal child handle — the subset of ChildProcess this module relies on. */
23
+ export interface ChildHandle {
24
+ once(event: "exit", listener: (code: number | null, signal: string | null) => void): unknown;
25
+ once(event: "error", listener: (error: NodeJS.ErrnoException) => void): unknown;
26
+ kill(signal?: NodeJS.Signals | number): boolean;
27
+ }
28
+ export interface SpawnOptions {
29
+ cwd: string;
30
+ env: NodeJS.ProcessEnv;
31
+ stdio: "inherit";
32
+ shell: false;
33
+ }
34
+ export type SpawnFn = (cmd: string, argv: readonly string[], opts: SpawnOptions) => ChildHandle;
35
+ export interface DelegateDeps {
36
+ readonly spawn?: SpawnFn;
37
+ readonly resolveBin?: (spec: DelegateSpec, cwd: string) => {
38
+ command: string;
39
+ argv: string[];
40
+ } | null;
41
+ readonly env?: NodeJS.ProcessEnv;
42
+ readonly cwd?: string;
43
+ readonly stderr?: NodeJS.WritableStream;
44
+ }
45
+ /** The jarvis spec, shared by the `xcoder` CLI and the aggregator's DISPATCH. */
46
+ export declare const JARVIS_SPEC: DelegateSpec;
47
+ export declare function isDelegableTarget(name: string): name is DelegableTarget;
48
+ /** The spec for an allowlisted target, or `undefined` for anything else. */
49
+ export declare function delegateSpec(target: string): DelegateSpec | undefined;
50
+ /**
51
+ * Resolve what to execute.
52
+ *
53
+ * The workspace build is tried first so a developer running from a checkout gets
54
+ * the code they just built; PATH is the declared fallback once published. The
55
+ * choice is returned so callers can log it (Spoofing control, design T4).
56
+ */
57
+ export declare function resolveDelegateCommand(spec: DelegateSpec, cwd: string): {
58
+ command: string;
59
+ argv: string[];
60
+ } | null;
61
+ /**
62
+ * Run the child with `argv` verbatim and return the code the parent must exit with.
63
+ *
64
+ * Never builds a command string, never parses, normalises, reorders or drops an
65
+ * argument, and never throws for an expected condition (spawn failure → 1).
66
+ */
67
+ export declare function runDelegated(spec: DelegateSpec, argv: readonly string[], deps?: DelegateDeps): Promise<number>;
68
+ /**
69
+ * Register `<target> [args...]` on `parent` with pure passthrough semantics.
70
+ *
71
+ * Registering makes the target discoverable in `xcoder --help`. Argument
72
+ * handling belongs to `extractDelegatedArg`, because commander would otherwise
73
+ * consume root options that the child legitimately accepts.
74
+ */
75
+ export declare function registerDelegatedCommand(parent: Command, spec: DelegateSpec): void;
76
+ export interface DelegatedInvocation {
77
+ readonly spec: DelegateSpec;
78
+ /** Everything after the target, untouched. */
79
+ readonly args: string[];
80
+ /** Index of the target token in the argv that was scanned. */
81
+ readonly index: number;
82
+ }
83
+ /**
84
+ * Detect a delegation from raw argv, before commander sees anything.
85
+ *
86
+ * Returns `undefined` for every ordinary invocation, so existing commands are
87
+ * parsed exactly as before. When a target is found, everything after it is
88
+ * returned untouched — the parent never validates a child flag.
89
+ */
90
+ export declare function extractDelegatedArg(argv: readonly string[]): DelegatedInvocation | undefined;
@@ -0,0 +1,220 @@
1
+ // xcoder:version 6 | xcoder:task task-691585 | xcoder:updated 2026-11-05T05:46:07.113Z | xcoder:subtask code-st-b5251b
2
+ // Cross-CLI delegation seam.
3
+ //
4
+ // `xcoder jarvis <args...>` runs the real `jarvis` binary in a child process
5
+ // and forwards every argument verbatim. This module owns that seam and nothing
6
+ // else: it does not know what jarvis does, and it never interprets a child flag.
7
+ //
8
+ // Why a subprocess and not an import: boundary rule 1 (`scripts/check-boundaries.mjs`)
9
+ // forbids one agent importing another, and the `xcoder` bin lives in
10
+ // `@xcoder/sdlc-agent`. The only legal shared home for this code is this library.
11
+ //
12
+ // Why argv is pre-extracted instead of parsed by commander: commander eagerly
13
+ // consumes root options (`--config`, `--workspace`) it sees after a subcommand,
14
+ // which would silently swallow a child flag. The workspace already solves this
15
+ // class of problem the same way for `--config` and `--wbc` (see `wbc-arg.ts`),
16
+ // so delegation follows that precedent rather than adding a new parsing mode.
17
+ import { spawn } from "node:child_process";
18
+ import { existsSync } from "node:fs";
19
+ import path from "node:path";
20
+ /** The closed allowlist of agent CLIs that may be reached through `xcoder`. */
21
+ export const DELEGABLE_TARGETS = ["jarvis", "litebro", "bugfinder"];
22
+ /** Shell convention for "command not found", identical on every platform. */
23
+ export const EXIT_ENOENT = 127;
24
+ /**
25
+ * Interrupted. POSIX would be 128+SIGINT (130); Windows has no signal-number
26
+ * convention, so one deterministic, testable constant is used everywhere.
27
+ */
28
+ export const EXIT_INTERRUPTED = 130;
29
+ /** The jarvis spec, shared by the `xcoder` CLI and the aggregator's DISPATCH. */
30
+ export const JARVIS_SPEC = {
31
+ target: "jarvis",
32
+ bin: "jarvis",
33
+ fallbackModule: path.join("packages", "jarvis-agent", "dist", "program.js"),
34
+ summary: "Jarvis — ReAct agent with scoped memory and an enforced tool allowlist",
35
+ };
36
+ const SPECS = {
37
+ jarvis: JARVIS_SPEC,
38
+ litebro: {
39
+ target: "litebro",
40
+ bin: "litebro",
41
+ fallbackModule: path.join("packages", "litebro", "dist", "cli.js"),
42
+ summary: "Litebro — tool-less planner/broker",
43
+ },
44
+ bugfinder: {
45
+ target: "bugfinder",
46
+ bin: "bugfinder",
47
+ fallbackModule: path.join("packages", "qa-agent", "dist", "qa-cli.js"),
48
+ summary: "Bugfinder — the QA agent",
49
+ },
50
+ };
51
+ export function isDelegableTarget(name) {
52
+ return DELEGABLE_TARGETS.includes(name);
53
+ }
54
+ /** The spec for an allowlisted target, or `undefined` for anything else. */
55
+ export function delegateSpec(target) {
56
+ return isDelegableTarget(target) ? SPECS[target] : undefined;
57
+ }
58
+ /**
59
+ * Resolve what to execute.
60
+ *
61
+ * The workspace build is tried first so a developer running from a checkout gets
62
+ * the code they just built; PATH is the declared fallback once published. The
63
+ * choice is returned so callers can log it (Spoofing control, design T4).
64
+ */
65
+ export function resolveDelegateCommand(spec, cwd) {
66
+ const local = path.resolve(cwd, spec.fallbackModule);
67
+ if (existsSync(local))
68
+ return { command: process.execPath, argv: [local] };
69
+ return { command: spec.bin, argv: [] };
70
+ }
71
+ function validTargetsMessage() {
72
+ return `valid targets: ${DELEGABLE_TARGETS.join(", ")}`;
73
+ }
74
+ /**
75
+ * Run the child with `argv` verbatim and return the code the parent must exit with.
76
+ *
77
+ * Never builds a command string, never parses, normalises, reorders or drops an
78
+ * argument, and never throws for an expected condition (spawn failure → 1).
79
+ */
80
+ export async function runDelegated(spec, argv, deps = {}) {
81
+ const stderr = deps.stderr ?? process.stderr;
82
+ if (!isDelegableTarget(spec.target)) {
83
+ stderr.write(`xcoder: '${spec.target}' is not a delegable target — ${validTargetsMessage()}\n`);
84
+ return 1;
85
+ }
86
+ const cwd = deps.cwd ?? process.cwd();
87
+ const resolve = deps.resolveBin ?? ((s, c) => resolveDelegateCommand(s, c));
88
+ const launch = resolve(spec, cwd);
89
+ if (launch === null) {
90
+ stderr.write(`xcoder: cannot find '${spec.bin}' — install it or build the workspace (${spec.fallbackModule}). ${validTargetsMessage()}\n`);
91
+ return EXIT_ENOENT;
92
+ }
93
+ if (deps.env?.XCODER_DELEGATE_VERBOSE ?? process.env.XCODER_DELEGATE_VERBOSE) {
94
+ // Counts and identifiers only: never the arguments themselves (no task text,
95
+ // no PII), never the environment.
96
+ stderr.write(`xcoder: delegating to ${spec.target} via ${launch.command} (${argv.length} argument${argv.length === 1 ? "" : "s"})\n`);
97
+ }
98
+ const spawnFn = deps.spawn ?? spawn;
99
+ const env = deps.env ?? process.env;
100
+ return new Promise((resolvePromise) => {
101
+ let child;
102
+ try {
103
+ child = spawnFn(launch.command, [...launch.argv, ...argv], {
104
+ cwd,
105
+ env,
106
+ stdio: "inherit",
107
+ shell: false,
108
+ });
109
+ }
110
+ catch (err) {
111
+ // Fail closed: a delegation that never started is not a success.
112
+ stderr.write(`xcoder: failed to start '${spec.bin}': ${err.message}\n`);
113
+ resolvePromise(1);
114
+ return;
115
+ }
116
+ const forward = (signal) => {
117
+ try {
118
+ child.kill(signal);
119
+ }
120
+ catch {
121
+ // The child is already gone; the exit handler owns the outcome.
122
+ }
123
+ };
124
+ const onSigint = () => forward("SIGINT");
125
+ const onSigterm = () => forward("SIGTERM");
126
+ process.on("SIGINT", onSigint);
127
+ process.on("SIGTERM", onSigterm);
128
+ const settle = (code) => {
129
+ process.off("SIGINT", onSigint);
130
+ process.off("SIGTERM", onSigterm);
131
+ resolvePromise(code);
132
+ };
133
+ child.once("error", (err) => {
134
+ if (err.code === "ENOENT") {
135
+ stderr.write(`xcoder: cannot find '${spec.bin}' — ${validTargetsMessage()}\n`);
136
+ settle(EXIT_ENOENT);
137
+ return;
138
+ }
139
+ stderr.write(`xcoder: '${spec.bin}' failed to start: ${err.message}\n`);
140
+ settle(1);
141
+ });
142
+ child.once("exit", (code, _signal) => {
143
+ if (code !== null) {
144
+ // The child's own exit code is the parent's, unchanged (0/1/2 all pass through).
145
+ settle(code);
146
+ return;
147
+ }
148
+ settle(EXIT_INTERRUPTED);
149
+ });
150
+ });
151
+ }
152
+ /**
153
+ * Register `<target> [args...]` on `parent` with pure passthrough semantics.
154
+ *
155
+ * Registering makes the target discoverable in `xcoder --help`. Argument
156
+ * handling belongs to `extractDelegatedArg`, because commander would otherwise
157
+ * consume root options that the child legitimately accepts.
158
+ */
159
+ export function registerDelegatedCommand(parent, spec) {
160
+ parent
161
+ .command(`${spec.target} [args...]`)
162
+ .description(`${spec.summary}. Every argument is forwarded verbatim.`)
163
+ .helpOption(false)
164
+ .allowUnknownOption(true)
165
+ .allowExcessArguments(true)
166
+ .action(async (_args, _opts, cmd) => {
167
+ const code = await runDelegated(spec, cmd.args);
168
+ process.exitCode = code;
169
+ });
170
+ }
171
+ /**
172
+ * Root options that take a value, so their value is never mistaken for a target.
173
+ *
174
+ * Closed on purpose: a wildcard here would let any argument become a command,
175
+ * and dropping an entry here would make `xcoder -task jarvis` run the `jarvis`
176
+ * binary instead of a task called "jarvis". Options with an *optional* value
177
+ * (`--resume`, `--debug-tools`) are listed too: their value can look exactly
178
+ * like a target, so the conservative reading is "do not delegate".
179
+ */
180
+ const ROOT_OPTIONS_WITH_VALUE = new Set([
181
+ "--config",
182
+ "-w",
183
+ "--workspace",
184
+ "--wbc",
185
+ "--wbs",
186
+ "-task",
187
+ "--task",
188
+ "--design",
189
+ "--code",
190
+ "--defect",
191
+ "--budget",
192
+ "--max-healing",
193
+ "-c",
194
+ "--concurrency",
195
+ "--model",
196
+ "--spinner",
197
+ "--resume",
198
+ "--debug-tools",
199
+ ]);
200
+ /**
201
+ * Detect a delegation from raw argv, before commander sees anything.
202
+ *
203
+ * Returns `undefined` for every ordinary invocation, so existing commands are
204
+ * parsed exactly as before. When a target is found, everything after it is
205
+ * returned untouched — the parent never validates a child flag.
206
+ */
207
+ export function extractDelegatedArg(argv) {
208
+ for (let i = 2; i < argv.length; i++) {
209
+ const token = argv[i];
210
+ if (ROOT_OPTIONS_WITH_VALUE.has(token)) {
211
+ i++; // skip this option's value
212
+ continue;
213
+ }
214
+ if (token.startsWith("-"))
215
+ continue;
216
+ const spec = delegateSpec(token);
217
+ return spec ? { spec, args: argv.slice(i + 1), index: i } : undefined;
218
+ }
219
+ return undefined;
220
+ }
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export { SubAgent } from "./agents/sub-agent.js";
7
7
  export { addBacklogItem, updateBacklogItem, listBacklogItems, getBacklogItem } from "./backlog/backlog-store.js";
8
8
  export { runPoPick } from "./backlog/po-agent.js";
9
9
  export { runBenchmark, compareReports } from "./bench/run.js";
10
+ export { DELEGABLE_TARGETS, EXIT_ENOENT, EXIT_INTERRUPTED, JARVIS_SPEC, delegateSpec, extractDelegatedArg, isDelegableTarget, registerDelegatedCommand, resolveDelegateCommand, runDelegated, type DelegateDeps, type DelegateSpec, type DelegableTarget } from "./cli/delegate.js";
10
11
  export { registerSwarmCommand } from "./cli/swarm.js";
11
12
  export { registerTaskCommand } from "./cli/task.js";
12
13
  export { extractWbcArg } from "./cli/wbc-arg.js";
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ // xcoder:version 2 | xcoder:task task-691585 | xcoder:updated 2026-11-05T05:45:12.986Z | xcoder:subtask code-st-b5251b
1
2
  // Public barrel — the only import path other packages may use.
2
3
  export { runDebate } from "./agents/ai-chat-debate.js";
3
4
  export { writeReport } from "./agents/ai-chat-report-writer.js";
@@ -8,6 +9,7 @@ export { SubAgent } from "./agents/sub-agent.js";
8
9
  export { addBacklogItem, updateBacklogItem, listBacklogItems, getBacklogItem } from "./backlog/backlog-store.js";
9
10
  export { runPoPick } from "./backlog/po-agent.js";
10
11
  export { runBenchmark, compareReports } from "./bench/run.js";
12
+ export { DELEGABLE_TARGETS, EXIT_ENOENT, EXIT_INTERRUPTED, JARVIS_SPEC, delegateSpec, extractDelegatedArg, isDelegableTarget, registerDelegatedCommand, resolveDelegateCommand, runDelegated } from "./cli/delegate.js";
11
13
  export { registerSwarmCommand } from "./cli/swarm.js";
12
14
  export { registerTaskCommand } from "./cli/task.js";
13
15
  export { extractWbcArg } from "./cli/wbc-arg.js";
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const XCODER_VERSION = "1.3.0";
1
+ export declare const XCODER_VERSION = "1.4.0";
2
2
  export declare const XCODER_BUILD_TIMESTAMP = "2026-10-26T00:00:00.000Z";
package/dist/version.js CHANGED
@@ -1,4 +1,5 @@
1
+ // xcoder:version 1 | xcoder:task task-762833 | xcoder:updated 2026-11-05T05:18:45.488Z | xcoder:subtask code-st-bb4289
1
2
  // AUTO-GENERATED by scripts/inject-version.mjs — DO NOT EDIT
2
3
  // Regenerate: npm run build (or: node scripts/inject-version.mjs)
3
- export const XCODER_VERSION = "1.3.0";
4
+ export const XCODER_VERSION = "1.4.0";
4
5
  export const XCODER_BUILD_TIMESTAMP = "2026-10-26T00:00:00.000Z";
package/package.json CHANGED
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "name": "xcoder-dna",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Reusable Xcoder components: tools, skills, swarm, sub-agent runtime and shared orchestration primitives.",
5
+ "license": "MIT",
6
+ "author": "Neural Node Labs",
5
7
  "type": "module",
6
8
  "engines": {
7
9
  "node": ">=20"
@@ -38,4 +40,4 @@
38
40
  "optionalDependencies": {
39
41
  "playwright": "^1.62.1"
40
42
  }
41
- }
43
+ }