@namzu/cli 2.0.0 → 2.1.1
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/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +8 -0
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/agent.d.ts +10 -0
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +10 -0
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/slashCommands.d.ts +46 -0
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/slashCommands.js +96 -0
- package/dist/tui/slashCommands.js.map +1 -1
- package/package.json +11 -6
- package/dist/__tests__/environment-reaches-the-turn.test.d.ts +0 -17
- package/dist/__tests__/environment-reaches-the-turn.test.d.ts.map +0 -1
- package/dist/__tests__/environment-reaches-the-turn.test.js +0 -128
- package/dist/__tests__/environment-reaches-the-turn.test.js.map +0 -1
- package/dist/__tests__/headless-trust-gate.test.d.ts +0 -23
- package/dist/__tests__/headless-trust-gate.test.d.ts.map +0 -1
- package/dist/__tests__/headless-trust-gate.test.js +0 -227
- package/dist/__tests__/headless-trust-gate.test.js.map +0 -1
- package/dist/__tests__/mcp-servers-reach-the-session.test.d.ts +0 -17
- package/dist/__tests__/mcp-servers-reach-the-session.test.d.ts.map +0 -1
- package/dist/__tests__/mcp-servers-reach-the-session.test.js +0 -171
- package/dist/__tests__/mcp-servers-reach-the-session.test.js.map +0 -1
- package/dist/__tests__/permission-rules-reach-the-turn.test.d.ts +0 -31
- package/dist/__tests__/permission-rules-reach-the-turn.test.d.ts.map +0 -1
- package/dist/__tests__/permission-rules-reach-the-turn.test.js +0 -132
- package/dist/__tests__/permission-rules-reach-the-turn.test.js.map +0 -1
- package/dist/__tests__/project-instructions-reach-the-turn.test.d.ts +0 -24
- package/dist/__tests__/project-instructions-reach-the-turn.test.d.ts.map +0 -1
- package/dist/__tests__/project-instructions-reach-the-turn.test.js +0 -153
- package/dist/__tests__/project-instructions-reach-the-turn.test.js.map +0 -1
- package/dist/cli.test.d.ts +0 -2
- package/dist/cli.test.d.ts.map +0 -1
- package/dist/cli.test.js +0 -108
- package/dist/cli.test.js.map +0 -1
- package/dist/commands/__tests__/eval.test.d.ts +0 -2
- package/dist/commands/__tests__/eval.test.d.ts.map +0 -1
- package/dist/commands/__tests__/eval.test.js +0 -165
- package/dist/commands/__tests__/eval.test.js.map +0 -1
- package/dist/commands/__tests__/passthrough-help.test.d.ts +0 -2
- package/dist/commands/__tests__/passthrough-help.test.d.ts.map +0 -1
- package/dist/commands/__tests__/passthrough-help.test.js +0 -96
- package/dist/commands/__tests__/passthrough-help.test.js.map +0 -1
- package/dist/commands/__tests__/resume.test.d.ts +0 -15
- package/dist/commands/__tests__/resume.test.d.ts.map +0 -1
- package/dist/commands/__tests__/resume.test.js +0 -116
- package/dist/commands/__tests__/resume.test.js.map +0 -1
- package/dist/commands/__tests__/run-exit-code.test.d.ts +0 -2
- package/dist/commands/__tests__/run-exit-code.test.d.ts.map +0 -1
- package/dist/commands/__tests__/run-exit-code.test.js +0 -100
- package/dist/commands/__tests__/run-exit-code.test.js.map +0 -1
- package/dist/commands/__tests__/run-flags.test.d.ts +0 -11
- package/dist/commands/__tests__/run-flags.test.d.ts.map +0 -1
- package/dist/commands/__tests__/run-flags.test.js +0 -238
- package/dist/commands/__tests__/run-flags.test.js.map +0 -1
- package/dist/commands/__tests__/run-stream-flags.test.d.ts +0 -2
- package/dist/commands/__tests__/run-stream-flags.test.d.ts.map +0 -1
- package/dist/commands/__tests__/run-stream-flags.test.js +0 -295
- package/dist/commands/__tests__/run-stream-flags.test.js.map +0 -1
- package/dist/commands/doctor.test.d.ts +0 -2
- package/dist/commands/doctor.test.d.ts.map +0 -1
- package/dist/commands/doctor.test.js +0 -82
- package/dist/commands/doctor.test.js.map +0 -1
- package/dist/config/load.test.d.ts +0 -2
- package/dist/config/load.test.d.ts.map +0 -1
- package/dist/config/load.test.js +0 -57
- package/dist/config/load.test.js.map +0 -1
- package/dist/context/__tests__/environment.test.d.ts +0 -10
- package/dist/context/__tests__/environment.test.d.ts.map +0 -1
- package/dist/context/__tests__/environment.test.js +0 -84
- package/dist/context/__tests__/environment.test.js.map +0 -1
- package/dist/context/__tests__/project.test.d.ts +0 -12
- package/dist/context/__tests__/project.test.d.ts.map +0 -1
- package/dist/context/__tests__/project.test.js +0 -201
- package/dist/context/__tests__/project.test.js.map +0 -1
- package/dist/doctor/checks/credentials.test.d.ts +0 -10
- package/dist/doctor/checks/credentials.test.d.ts.map +0 -1
- package/dist/doctor/checks/credentials.test.js +0 -47
- package/dist/doctor/checks/credentials.test.js.map +0 -1
- package/dist/doctor/checks/sandbox.test.d.ts +0 -2
- package/dist/doctor/checks/sandbox.test.d.ts.map +0 -1
- package/dist/doctor/checks/sandbox.test.js +0 -59
- package/dist/doctor/checks/sandbox.test.js.map +0 -1
- package/dist/doctor/registry.test.d.ts +0 -7
- package/dist/doctor/registry.test.d.ts.map +0 -1
- package/dist/doctor/registry.test.js +0 -379
- package/dist/doctor/registry.test.js.map +0 -1
- package/dist/integrations/mcp/__tests__/connect.test.d.ts +0 -11
- package/dist/integrations/mcp/__tests__/connect.test.d.ts.map +0 -1
- package/dist/integrations/mcp/__tests__/connect.test.js +0 -231
- package/dist/integrations/mcp/__tests__/connect.test.js.map +0 -1
- package/dist/integrations/providers/discover.test.d.ts +0 -2
- package/dist/integrations/providers/discover.test.d.ts.map +0 -1
- package/dist/integrations/providers/discover.test.js +0 -93
- package/dist/integrations/providers/discover.test.js.map +0 -1
- package/dist/integrations/providers/keychain.test.d.ts +0 -2
- package/dist/integrations/providers/keychain.test.d.ts.map +0 -1
- package/dist/integrations/providers/keychain.test.js +0 -21
- package/dist/integrations/providers/keychain.test.js.map +0 -1
- package/dist/integrations/providers/oauth.test.d.ts +0 -2
- package/dist/integrations/providers/oauth.test.d.ts.map +0 -1
- package/dist/integrations/providers/oauth.test.js +0 -86
- package/dist/integrations/providers/oauth.test.js.map +0 -1
- package/dist/integrations/providers/preferences.test.d.ts +0 -2
- package/dist/integrations/providers/preferences.test.d.ts.map +0 -1
- package/dist/integrations/providers/preferences.test.js +0 -76
- package/dist/integrations/providers/preferences.test.js.map +0 -1
- package/dist/integrations/sessions/__tests__/archived-workspace.test.d.ts +0 -21
- package/dist/integrations/sessions/__tests__/archived-workspace.test.d.ts.map +0 -1
- package/dist/integrations/sessions/__tests__/archived-workspace.test.js +0 -62
- package/dist/integrations/sessions/__tests__/archived-workspace.test.js.map +0 -1
- package/dist/integrations/subagents/__tests__/delegation-trace.test.d.ts +0 -2
- package/dist/integrations/subagents/__tests__/delegation-trace.test.d.ts.map +0 -1
- package/dist/integrations/subagents/__tests__/delegation-trace.test.js +0 -114
- package/dist/integrations/subagents/__tests__/delegation-trace.test.js.map +0 -1
- package/dist/integrations/trust/store.test.d.ts +0 -2
- package/dist/integrations/trust/store.test.d.ts.map +0 -1
- package/dist/integrations/trust/store.test.js +0 -50
- package/dist/integrations/trust/store.test.js.map +0 -1
- package/dist/memory/store.test.d.ts +0 -2
- package/dist/memory/store.test.d.ts.map +0 -1
- package/dist/memory/store.test.js +0 -63
- package/dist/memory/store.test.js.map +0 -1
- package/dist/output/formatter.test.d.ts +0 -2
- package/dist/output/formatter.test.d.ts.map +0 -1
- package/dist/output/formatter.test.js +0 -88
- package/dist/output/formatter.test.js.map +0 -1
- package/dist/output/rendered-payload.test.d.ts +0 -2
- package/dist/output/rendered-payload.test.d.ts.map +0 -1
- package/dist/output/rendered-payload.test.js +0 -61
- package/dist/output/rendered-payload.test.js.map +0 -1
- package/dist/permissions/__tests__/mode.test.d.ts +0 -10
- package/dist/permissions/__tests__/mode.test.d.ts.map +0 -1
- package/dist/permissions/__tests__/mode.test.js +0 -115
- package/dist/permissions/__tests__/mode.test.js.map +0 -1
- package/dist/permissions/__tests__/rules.test.d.ts +0 -10
- package/dist/permissions/__tests__/rules.test.d.ts.map +0 -1
- package/dist/permissions/__tests__/rules.test.js +0 -196
- package/dist/permissions/__tests__/rules.test.js.map +0 -1
- package/dist/skills/store.test.d.ts +0 -2
- package/dist/skills/store.test.d.ts.map +0 -1
- package/dist/skills/store.test.js +0 -80
- package/dist/skills/store.test.js.map +0 -1
- package/dist/tui/__tests__/context-gauge.test.d.ts +0 -2
- package/dist/tui/__tests__/context-gauge.test.d.ts.map +0 -1
- package/dist/tui/__tests__/context-gauge.test.js +0 -83
- package/dist/tui/__tests__/context-gauge.test.js.map +0 -1
- package/dist/tui/__tests__/deferred-tool-discovery.test.d.ts +0 -24
- package/dist/tui/__tests__/deferred-tool-discovery.test.d.ts.map +0 -1
- package/dist/tui/__tests__/deferred-tool-discovery.test.js +0 -111
- package/dist/tui/__tests__/deferred-tool-discovery.test.js.map +0 -1
- package/dist/tui/__tests__/to-agent-event.test.d.ts +0 -2
- package/dist/tui/__tests__/to-agent-event.test.d.ts.map +0 -1
- package/dist/tui/__tests__/to-agent-event.test.js +0 -230
- package/dist/tui/__tests__/to-agent-event.test.js.map +0 -1
- package/dist/tui/__tests__/working-directory.test.d.ts +0 -13
- package/dist/tui/__tests__/working-directory.test.d.ts.map +0 -1
- package/dist/tui/__tests__/working-directory.test.js +0 -109
- package/dist/tui/__tests__/working-directory.test.js.map +0 -1
- package/dist/tui/agent.test.d.ts +0 -2
- package/dist/tui/agent.test.d.ts.map +0 -1
- package/dist/tui/agent.test.js +0 -225
- package/dist/tui/agent.test.js.map +0 -1
- package/dist/tui/markdownParser.test.d.ts +0 -2
- package/dist/tui/markdownParser.test.d.ts.map +0 -1
- package/dist/tui/markdownParser.test.js +0 -90
- package/dist/tui/markdownParser.test.js.map +0 -1
- package/dist/tui/mentions.test.d.ts +0 -2
- package/dist/tui/mentions.test.d.ts.map +0 -1
- package/dist/tui/mentions.test.js +0 -35
- package/dist/tui/mentions.test.js.map +0 -1
- package/dist/tui/slashCommands.test.d.ts +0 -2
- package/dist/tui/slashCommands.test.d.ts.map +0 -1
- package/dist/tui/slashCommands.test.js +0 -114
- package/dist/tui/slashCommands.test.js.map +0 -1
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A closed workspace takes no new conversation from the CLI either.
|
|
3
|
-
*
|
|
4
|
-
* The kernel gained a workspace-closed gate and it was applied to the SDK's own
|
|
5
|
-
* ingress paths. `startConversation` calls `createSession` on the store
|
|
6
|
-
* DIRECTLY, and a store deliberately holds no view of workspace status, so the
|
|
7
|
-
* invariant did not reach here.
|
|
8
|
-
*
|
|
9
|
-
* Whether that mattered turned on one question a grep cannot answer: does the
|
|
10
|
-
* CLI ever reach a project it did not just create? It does. `openSessions`
|
|
11
|
-
* reads the project id back out of `.namzu/cli.json` and creates a new project
|
|
12
|
-
* only when the pointer is missing or stale — so every run after the first
|
|
13
|
-
* attaches to a project that already existed and may since have been closed.
|
|
14
|
-
*
|
|
15
|
-
* That is why this test archives a project created by an EARLIER `openSessions`
|
|
16
|
-
* and then reopens the same directory. A test that archived a project it made
|
|
17
|
-
* itself, in one call, would pass against the first-run case the gate can never
|
|
18
|
-
* fire on.
|
|
19
|
-
*/
|
|
20
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
21
|
-
import { tmpdir } from 'node:os';
|
|
22
|
-
import { join } from 'node:path';
|
|
23
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
24
|
-
import { ProjectManager, UNKNOWN_TENANT_ID } from '@namzu/sdk';
|
|
25
|
-
import { openSessions, startConversation } from '../store.js';
|
|
26
|
-
let cwd;
|
|
27
|
-
beforeEach(() => {
|
|
28
|
-
cwd = mkdtempSync(join(tmpdir(), 'namzu-archived-'));
|
|
29
|
-
});
|
|
30
|
-
afterEach(() => {
|
|
31
|
-
rmSync(cwd, { recursive: true, force: true });
|
|
32
|
-
});
|
|
33
|
-
describe('a workspace its owner has closed', () => {
|
|
34
|
-
it('refuses a new conversation, instead of quietly accepting work', async () => {
|
|
35
|
-
// First run: creates the project and writes the pointer.
|
|
36
|
-
const first = await openSessions(cwd);
|
|
37
|
-
await new ProjectManager({ store: first.store }).archive(first.projectId, UNKNOWN_TENANT_ID);
|
|
38
|
-
// A later run in the same directory reaches the SAME project through the
|
|
39
|
-
// pointer — the case that exists only from the second run onward.
|
|
40
|
-
const later = await openSessions(cwd);
|
|
41
|
-
expect(later.projectId, 'the pointer has to be what makes this reachable').toBe(first.projectId);
|
|
42
|
-
await expect(startConversation(later)).rejects.toThrow(/archiv|closed/i);
|
|
43
|
-
});
|
|
44
|
-
it('still starts a conversation in an open one', async () => {
|
|
45
|
-
// The other half. A gate nothing can get past has broken the product,
|
|
46
|
-
// and this is the assertion that would catch a `requireOpenProject` call
|
|
47
|
-
// wired to the wrong project id.
|
|
48
|
-
const sessions = await openSessions(cwd);
|
|
49
|
-
const id = await startConversation(sessions);
|
|
50
|
-
expect(typeof id).toBe('string');
|
|
51
|
-
expect(id.length).toBeGreaterThan(0);
|
|
52
|
-
});
|
|
53
|
-
it('names the workspace in the refusal', async () => {
|
|
54
|
-
// A refusal that does not say which workspace sends the reader nowhere:
|
|
55
|
-
// the whole point is that an owner closed this one on purpose.
|
|
56
|
-
const first = await openSessions(cwd);
|
|
57
|
-
await new ProjectManager({ store: first.store }).archive(first.projectId, UNKNOWN_TENANT_ID);
|
|
58
|
-
const later = await openSessions(cwd);
|
|
59
|
-
await expect(startConversation(later)).rejects.toThrow(new RegExp(later.projectId));
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
//# sourceMappingURL=archived-workspace.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"archived-workspace.test.js","sourceRoot":"","sources":["../../../../src/integrations/sessions/__tests__/archived-workspace.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAEpE,OAAO,EAAE,cAAc,EAAiB,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE7E,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAE7D,IAAI,GAAW,CAAA;AAEf,UAAU,CAAC,GAAG,EAAE;IACf,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAA;AACrD,CAAC,CAAC,CAAA;AAEF,SAAS,CAAC,GAAG,EAAE;IACd,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;AAC9C,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC9E,yDAAyD;QACzD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CACvD,KAAK,CAAC,SAAS,EACf,iBAA6B,CAC7B,CAAA;QAED,yEAAyE;QACzE,kEAAkE;QAClE,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,iDAAiD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAEhG,MAAM,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACzE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC3D,sEAAsE;QACtE,yEAAyE;QACzE,iCAAiC;QACjC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QAExC,MAAM,EAAE,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QAE5C,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAChC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QACnD,wEAAwE;QACxE,+DAA+D;QAC/D,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CACvD,KAAK,CAAC,SAAS,EACf,iBAA6B,CAC7B,CAAA;QAED,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QAErC,MAAM,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;IACpF,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"delegation-trace.test.d.ts","sourceRoot":"","sources":["../../../../src/integrations/subagents/__tests__/delegation-trace.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { AgentRegistry, LocalTaskGateway, } from '@namzu/sdk';
|
|
3
|
-
import { createSubagentRuntime } from '../runtime.js';
|
|
4
|
-
/**
|
|
5
|
-
* A delegated run belongs inside the turn that asked for it.
|
|
6
|
-
*
|
|
7
|
-
* The kernel supports this end to end — the executing tool's span reaches
|
|
8
|
-
* `createTask`, survives `configOverrides`, is stamped onto the child config
|
|
9
|
-
* after the host's `configBuilder` runs, and becomes the child run's trace
|
|
10
|
-
* parent. Every hop was built and tested. The `Agent` tool simply did not pass
|
|
11
|
-
* the first one, so a sub-agent opened its own ROOT trace and the delegation
|
|
12
|
-
* structure — the one thing a delegation trace exists to record — was absent.
|
|
13
|
-
*
|
|
14
|
-
* The gateway is constructed inside the runtime, so the spy goes on its
|
|
15
|
-
* prototype: this drives the real tool through the real wiring rather than
|
|
16
|
-
* re-deriving what the tool ought to do. A unit test on the span helper would
|
|
17
|
-
* have passed throughout the defect.
|
|
18
|
-
*/
|
|
19
|
-
const fakeSpan = { __brand: 'span' };
|
|
20
|
-
function toolContext(parentSpan) {
|
|
21
|
-
return { runId: 'run_test', ...(parentSpan ? { parentSpan } : {}) };
|
|
22
|
-
}
|
|
23
|
-
async function buildAgentTool(extra = {}) {
|
|
24
|
-
const created = [];
|
|
25
|
-
const registered = [];
|
|
26
|
-
vi.spyOn(AgentRegistry.prototype, 'register').mockImplementation((def) => {
|
|
27
|
-
for (const d of Array.isArray(def) ? def : [def])
|
|
28
|
-
registered.push(d);
|
|
29
|
-
});
|
|
30
|
-
vi.spyOn(LocalTaskGateway.prototype, 'createTask').mockImplementation(async (options) => {
|
|
31
|
-
created.push(options);
|
|
32
|
-
return { taskId: 'tsk_1' };
|
|
33
|
-
});
|
|
34
|
-
vi.spyOn(LocalTaskGateway.prototype, 'waitForTask').mockResolvedValue({
|
|
35
|
-
state: 'completed',
|
|
36
|
-
result: { status: 'completed', result: 'done' },
|
|
37
|
-
});
|
|
38
|
-
const runtime = await createSubagentRuntime({
|
|
39
|
-
cwd: '/tmp',
|
|
40
|
-
model: 'test-model',
|
|
41
|
-
buildProvider: () => ({}),
|
|
42
|
-
buildTools: () => ({}),
|
|
43
|
-
...extra,
|
|
44
|
-
});
|
|
45
|
-
return { agentTool: runtime.agentTool, created, registered };
|
|
46
|
-
}
|
|
47
|
-
afterEach(() => {
|
|
48
|
-
vi.restoreAllMocks();
|
|
49
|
-
});
|
|
50
|
-
describe('the Agent tool parents a delegated run to the turn that asked for it', () => {
|
|
51
|
-
it('passes the executing tool span through to the child run', async () => {
|
|
52
|
-
const { agentTool, created } = await buildAgentTool();
|
|
53
|
-
await agentTool.execute({ description: 'audit', prompt: 'do a thing' }, toolContext(fakeSpan));
|
|
54
|
-
expect(created).toHaveLength(1);
|
|
55
|
-
expect(created[0]?.parentSpan).toBe(fakeSpan);
|
|
56
|
-
});
|
|
57
|
-
it('omits the key entirely when the turn supplied no span', async () => {
|
|
58
|
-
// Not the same as passing `undefined`: the kernel branches on the
|
|
59
|
-
// property's presence, and a top-level run with no parent is correct
|
|
60
|
-
// to start its own root. Refusing to invent one is the other half of
|
|
61
|
-
// the fix, not an edge case.
|
|
62
|
-
const { agentTool, created } = await buildAgentTool();
|
|
63
|
-
await agentTool.execute({ description: 'audit', prompt: 'do a thing' }, toolContext());
|
|
64
|
-
expect(created[0]).not.toHaveProperty('parentSpan');
|
|
65
|
-
});
|
|
66
|
-
it('parents a dynamically defined specialist too', async () => {
|
|
67
|
-
// The `role` branch registers a fresh agent before delegating, and it
|
|
68
|
-
// is a second path to the same `createTask`. One of two paths carrying
|
|
69
|
-
// a signal is how this class of defect survives a green suite.
|
|
70
|
-
const { agentTool, created } = await buildAgentTool();
|
|
71
|
-
await agentTool.execute({ description: 'audit', prompt: 'do a thing', role: 'You are an auditor' }, toolContext(fakeSpan));
|
|
72
|
-
expect(created[0]?.parentSpan).toBe(fakeSpan);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
/**
|
|
76
|
-
* The project's standing instructions bind a specialist the model invents at
|
|
77
|
-
* call time, not only the pre-registered general-purpose sub-agent.
|
|
78
|
-
*
|
|
79
|
-
* `role` is a SECOND registration path to the same definition builder, and one
|
|
80
|
-
* of two paths carrying a signal is how this class of defect survives a green
|
|
81
|
-
* suite: the delegation everyone tests would honour the project's rules and
|
|
82
|
-
* the one the model actually reaches for — a named specialist — would not.
|
|
83
|
-
*/
|
|
84
|
-
describe('a sub-agent is bound by the project it works in', () => {
|
|
85
|
-
const INSTRUCTIONS = '## Project instructions\n\nNever use a default export.';
|
|
86
|
-
it('gives the general-purpose sub-agent the block', async () => {
|
|
87
|
-
const { registered } = await buildAgentTool({ projectInstructions: INSTRUCTIONS });
|
|
88
|
-
const general = registered.find((d) => d.info.id === 'general-purpose');
|
|
89
|
-
const config = (await general?.configBuilder?.({}));
|
|
90
|
-
expect(config?.systemPrompt).toContain('Never use a default export.');
|
|
91
|
-
});
|
|
92
|
-
it('gives a specialist defined at call time the same block', async () => {
|
|
93
|
-
const { agentTool, registered } = await buildAgentTool({ projectInstructions: INSTRUCTIONS });
|
|
94
|
-
await agentTool.execute({ description: 'audit', prompt: 'do a thing', role: 'You are a security auditor' }, toolContext());
|
|
95
|
-
const specialist = registered.find((d) => d.info.id.startsWith('dyn-'));
|
|
96
|
-
if (!specialist?.configBuilder) {
|
|
97
|
-
throw new Error('no dynamic specialist was registered — this test proves nothing');
|
|
98
|
-
}
|
|
99
|
-
const prompt = String((await specialist.configBuilder({})).systemPrompt ?? '');
|
|
100
|
-
expect(prompt).toContain('You are a security auditor');
|
|
101
|
-
expect(prompt).toContain('Never fabricate.');
|
|
102
|
-
expect(prompt).toContain('Never use a default export.');
|
|
103
|
-
// Order is the containment: a persona and a project file are both text
|
|
104
|
-
// the model can influence, and both sit after the guardrails.
|
|
105
|
-
expect(prompt.indexOf('Never fabricate.')).toBeLessThan(prompt.indexOf('Never use a default export.'));
|
|
106
|
-
});
|
|
107
|
-
it('adds nothing when the project declares none', async () => {
|
|
108
|
-
const { registered } = await buildAgentTool();
|
|
109
|
-
const general = registered.find((d) => d.info.id === 'general-purpose');
|
|
110
|
-
const config = (await general?.configBuilder?.({}));
|
|
111
|
-
expect(config?.systemPrompt).not.toContain('Project instructions');
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
//# sourceMappingURL=delegation-trace.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"delegation-trace.test.js","sourceRoot":"","sources":["../../../../src/integrations/subagents/__tests__/delegation-trace.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.test.d.ts","sourceRoot":"","sources":["../../../src/integrations/trust/store.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { mkdirSync, mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
-
import { tmpdir } from 'node:os';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
-
import { isTrusted, readTrustedDirs, trustDir } from './store.js';
|
|
6
|
-
let home;
|
|
7
|
-
let work;
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
home = mkdtempSync(join(tmpdir(), 'namzu-trust-'));
|
|
10
|
-
work = mkdtempSync(join(tmpdir(), 'namzu-proj-'));
|
|
11
|
-
mkdirSync(join(home, '.namzu'), { recursive: true });
|
|
12
|
-
});
|
|
13
|
-
afterEach(() => {
|
|
14
|
-
rmSync(home, { recursive: true, force: true });
|
|
15
|
-
rmSync(work, { recursive: true, force: true });
|
|
16
|
-
});
|
|
17
|
-
describe('trust store', () => {
|
|
18
|
-
it('starts empty and untrusted', () => {
|
|
19
|
-
expect(readTrustedDirs(home)).toEqual([]);
|
|
20
|
-
expect(isTrusted(work, home)).toBe(false);
|
|
21
|
-
});
|
|
22
|
-
it('trusts a directory and persists it', () => {
|
|
23
|
-
trustDir(work, home);
|
|
24
|
-
expect(isTrusted(work, home)).toBe(true);
|
|
25
|
-
expect(readTrustedDirs(home).length).toBe(1);
|
|
26
|
-
});
|
|
27
|
-
it('is idempotent', () => {
|
|
28
|
-
trustDir(work, home);
|
|
29
|
-
trustDir(work, home);
|
|
30
|
-
expect(readTrustedDirs(home).length).toBe(1);
|
|
31
|
-
});
|
|
32
|
-
it('trusting a folder covers its subfolders (ancestor match)', () => {
|
|
33
|
-
const sub = join(work, 'packages', 'cli');
|
|
34
|
-
mkdirSync(sub, { recursive: true });
|
|
35
|
-
trustDir(work, home);
|
|
36
|
-
expect(isTrusted(sub, home)).toBe(true);
|
|
37
|
-
});
|
|
38
|
-
it('does not trust an unrelated sibling', () => {
|
|
39
|
-
const other = mkdtempSync(join(tmpdir(), 'namzu-other-'));
|
|
40
|
-
trustDir(work, home);
|
|
41
|
-
expect(isTrusted(other, home)).toBe(false);
|
|
42
|
-
rmSync(other, { recursive: true, force: true });
|
|
43
|
-
});
|
|
44
|
-
it('does not treat a path-prefix sibling as trusted', () => {
|
|
45
|
-
// /tmp/proj must not match /tmp/proj-2 just by string prefix.
|
|
46
|
-
trustDir(work, home);
|
|
47
|
-
expect(isTrusted(`${work}-2`, home)).toBe(false);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
//# sourceMappingURL=store.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.test.js","sourceRoot":"","sources":["../../../src/integrations/trust/store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.test.d.ts","sourceRoot":"","sources":["../../src/memory/store.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { mkdirSync } from 'node:fs';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
6
|
-
import { appendMemory, composeMemoryPrompt, memoryFilePath, readMemory, userFilePath, } from './store.js';
|
|
7
|
-
let home;
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
home = mkdtempSync(join(tmpdir(), 'namzu-mem-'));
|
|
10
|
-
mkdirSync(join(home, '.namzu'), { recursive: true });
|
|
11
|
-
});
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
rmSync(home, { recursive: true, force: true });
|
|
14
|
-
});
|
|
15
|
-
describe('readMemory', () => {
|
|
16
|
-
it('returns nulls when nothing is stored', () => {
|
|
17
|
-
expect(readMemory(home)).toEqual({ user: null, memory: null });
|
|
18
|
-
});
|
|
19
|
-
it('reads USER.md and MEMORY.md and trims', () => {
|
|
20
|
-
writeFileSync(userFilePath(home), ' I am Bahadir, a TS dev.\n');
|
|
21
|
-
writeFileSync(memoryFilePath(home), '- prefers tabs\n');
|
|
22
|
-
expect(readMemory(home)).toEqual({
|
|
23
|
-
user: 'I am Bahadir, a TS dev.',
|
|
24
|
-
memory: '- prefers tabs',
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
it('treats whitespace-only files as empty', () => {
|
|
28
|
-
writeFileSync(memoryFilePath(home), ' \n\n');
|
|
29
|
-
expect(readMemory(home).memory).toBeNull();
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
describe('composeMemoryPrompt', () => {
|
|
33
|
-
it('returns null when there is nothing to inject', () => {
|
|
34
|
-
expect(composeMemoryPrompt({ user: null, memory: null })).toBeNull();
|
|
35
|
-
});
|
|
36
|
-
it('includes only the sections that have content', () => {
|
|
37
|
-
const onlyUser = composeMemoryPrompt({ user: 'role: dev', memory: null });
|
|
38
|
-
expect(onlyUser).toContain('## About the user');
|
|
39
|
-
expect(onlyUser).toContain('role: dev');
|
|
40
|
-
expect(onlyUser).not.toContain('## Durable memory');
|
|
41
|
-
const both = composeMemoryPrompt({ user: 'role: dev', memory: '- likes tabs' });
|
|
42
|
-
expect(both).toContain('## About the user');
|
|
43
|
-
expect(both).toContain('## Durable memory');
|
|
44
|
-
expect(both).toContain('- likes tabs');
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
describe('appendMemory', () => {
|
|
48
|
-
it('appends a bullet, creating the file', () => {
|
|
49
|
-
appendMemory('first fact', home);
|
|
50
|
-
appendMemory('second fact', home);
|
|
51
|
-
expect(readFileSync(memoryFilePath(home), 'utf8')).toBe('- first fact\n- second fact\n');
|
|
52
|
-
});
|
|
53
|
-
it('ignores empty input', () => {
|
|
54
|
-
appendMemory(' ', home);
|
|
55
|
-
expect(readMemory(home).memory).toBeNull();
|
|
56
|
-
});
|
|
57
|
-
it('round-trips into the injected prompt', () => {
|
|
58
|
-
appendMemory('namzu is built on @namzu/sdk', home);
|
|
59
|
-
const prompt = composeMemoryPrompt(readMemory(home));
|
|
60
|
-
expect(prompt).toContain('namzu is built on @namzu/sdk');
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
//# sourceMappingURL=store.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.test.js","sourceRoot":"","sources":["../../src/memory/store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatter.test.d.ts","sourceRoot":"","sources":["../../src/output/formatter.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { createFormatter, isFormatName } from './index.js';
|
|
3
|
-
describe('formatter factory', () => {
|
|
4
|
-
let stdout;
|
|
5
|
-
let stderr;
|
|
6
|
-
let originalStdoutWrite;
|
|
7
|
-
let originalStderrWrite;
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
stdout = '';
|
|
10
|
-
stderr = '';
|
|
11
|
-
originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
12
|
-
originalStderrWrite = process.stderr.write.bind(process.stderr);
|
|
13
|
-
process.stdout.write = ((chunk) => {
|
|
14
|
-
stdout += typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
|
|
15
|
-
return true;
|
|
16
|
-
});
|
|
17
|
-
process.stderr.write = ((chunk) => {
|
|
18
|
-
stderr += typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
|
|
19
|
-
return true;
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
process.stdout.write = originalStdoutWrite;
|
|
24
|
-
process.stderr.write = originalStderrWrite;
|
|
25
|
-
});
|
|
26
|
-
it('isFormatName narrows known names', () => {
|
|
27
|
-
expect(isFormatName('text')).toBe(true);
|
|
28
|
-
expect(isFormatName('json')).toBe(true);
|
|
29
|
-
expect(isFormatName('yaml')).toBe(true);
|
|
30
|
-
expect(isFormatName('xml')).toBe(false);
|
|
31
|
-
});
|
|
32
|
-
it('json formatter emits parseable JSON to stdout', () => {
|
|
33
|
-
const f = createFormatter('json', { quiet: false });
|
|
34
|
-
f.print({ hello: 'world', n: 1 });
|
|
35
|
-
const parsed = JSON.parse(stdout);
|
|
36
|
-
expect(parsed.hello).toBe('world');
|
|
37
|
-
expect(parsed.n).toBe(1);
|
|
38
|
-
});
|
|
39
|
-
it('yaml formatter emits yaml to stdout', () => {
|
|
40
|
-
const f = createFormatter('yaml', { quiet: false });
|
|
41
|
-
f.print({ hello: 'world' });
|
|
42
|
-
expect(stdout).toContain('hello: world');
|
|
43
|
-
});
|
|
44
|
-
it('text formatter passes strings through verbatim', () => {
|
|
45
|
-
const f = createFormatter('text', { quiet: false });
|
|
46
|
-
f.print('hello');
|
|
47
|
-
expect(stdout).toBe('hello\n');
|
|
48
|
-
});
|
|
49
|
-
it('info is suppressed in quiet mode for every format', () => {
|
|
50
|
-
for (const name of ['text', 'json', 'yaml']) {
|
|
51
|
-
stdout = '';
|
|
52
|
-
stderr = '';
|
|
53
|
-
const f = createFormatter(name, { quiet: true });
|
|
54
|
-
f.info('this should not appear');
|
|
55
|
-
expect(stderr).toBe('');
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
it('errors are never suppressed by quiet mode', () => {
|
|
59
|
-
for (const name of ['text', 'json', 'yaml']) {
|
|
60
|
-
stdout = '';
|
|
61
|
-
stderr = '';
|
|
62
|
-
const f = createFormatter(name, { quiet: true });
|
|
63
|
-
f.error({ message: 'boom' });
|
|
64
|
-
expect(stderr).toContain('boom');
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
it('json formatter does not crash on circular references', () => {
|
|
68
|
-
const f = createFormatter('json', { quiet: false });
|
|
69
|
-
const obj = { a: 1 };
|
|
70
|
-
obj.self = obj;
|
|
71
|
-
f.print(obj);
|
|
72
|
-
expect(stdout).toContain('"a": 1');
|
|
73
|
-
expect(stdout).toContain('[Circular]');
|
|
74
|
-
});
|
|
75
|
-
it('text formatter does not blow the stack on circular references', () => {
|
|
76
|
-
const f = createFormatter('text', { quiet: false });
|
|
77
|
-
const obj = { a: 1 };
|
|
78
|
-
obj.self = obj;
|
|
79
|
-
f.print(obj);
|
|
80
|
-
expect(stdout).toContain('Circular');
|
|
81
|
-
});
|
|
82
|
-
it('json formatter serializes bigint via toString instead of throwing', () => {
|
|
83
|
-
const f = createFormatter('json', { quiet: false });
|
|
84
|
-
f.print({ big: 12345678901234567890n });
|
|
85
|
-
expect(stdout).toContain('12345678901234567890');
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
//# sourceMappingURL=formatter.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatter.test.js","sourceRoot":"","sources":["../../src/output/formatter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rendered-payload.test.d.ts","sourceRoot":"","sources":["../../src/output/rendered-payload.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { createFormatter } from './index.js';
|
|
3
|
-
/**
|
|
4
|
-
* A payload that brought its own rendering gets to use it.
|
|
5
|
-
*
|
|
6
|
-
* Without this a command has to choose between the structured payload the
|
|
7
|
-
* `json` and `yaml` formats need and the human string `text` needs — so a
|
|
8
|
-
* command that wants both passes the object, and the text format dumps a
|
|
9
|
-
* nested object graph where a report was meant to be.
|
|
10
|
-
*
|
|
11
|
-
* `namzu eval` did exactly that in its default format, with the readable
|
|
12
|
-
* version sitting unused one level down. No test caught it: the command's
|
|
13
|
-
* own tests asserted on the payload, which was correct, and never on what
|
|
14
|
-
* a person sees. It was found by running the built binary.
|
|
15
|
-
*/
|
|
16
|
-
describe('a payload carrying its own text', () => {
|
|
17
|
-
let stdout;
|
|
18
|
-
let restore;
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
stdout = '';
|
|
21
|
-
restore = process.stdout.write.bind(process.stdout);
|
|
22
|
-
process.stdout.write = ((chunk) => {
|
|
23
|
-
stdout += typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
|
|
24
|
-
return true;
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
afterEach(() => {
|
|
28
|
-
process.stdout.write = restore;
|
|
29
|
-
});
|
|
30
|
-
const payload = {
|
|
31
|
-
suite: 'kernel',
|
|
32
|
-
report: { name: 'kernel-smoke', passed: 1, failed: 0 },
|
|
33
|
-
text: 'kernel-smoke: 1/1 passed (mean 1.00)',
|
|
34
|
-
};
|
|
35
|
-
it('renders the text, not the object graph, in text format', () => {
|
|
36
|
-
createFormatter('text', { quiet: false }).print(payload);
|
|
37
|
-
expect(stdout.trim()).toBe('kernel-smoke: 1/1 passed (mean 1.00)');
|
|
38
|
-
// The tell that this regressed: the reader sees field names.
|
|
39
|
-
expect(stdout).not.toContain('suite:');
|
|
40
|
-
expect(stdout).not.toContain('report:');
|
|
41
|
-
});
|
|
42
|
-
it('still emits the whole payload as json', () => {
|
|
43
|
-
// The structured half is what a CI job parses; collapsing to the
|
|
44
|
-
// string would trade one broken format for another.
|
|
45
|
-
createFormatter('json', { quiet: false }).print(payload);
|
|
46
|
-
const parsed = JSON.parse(stdout);
|
|
47
|
-
expect(parsed.report.passed).toBe(1);
|
|
48
|
-
expect(parsed.suite).toBe('kernel');
|
|
49
|
-
});
|
|
50
|
-
it('leaves a payload without a text field alone', () => {
|
|
51
|
-
createFormatter('text', { quiet: false }).print({ tools: ['read', 'edit'] });
|
|
52
|
-
expect(stdout).toContain('read');
|
|
53
|
-
});
|
|
54
|
-
it('does not treat a non-string text field as rendering', () => {
|
|
55
|
-
// A payload whose `text` is a number is data, not a rendering; using
|
|
56
|
-
// it would hide every other field.
|
|
57
|
-
createFormatter('text', { quiet: false }).print({ text: 42, other: 'kept' });
|
|
58
|
-
expect(stdout).toContain('other');
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
//# sourceMappingURL=rendered-payload.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rendered-payload.test.js","sourceRoot":"","sources":["../../src/output/rendered-payload.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The mode, and its precedence against the config file.
|
|
3
|
-
*
|
|
4
|
-
* The rule being protected is one sentence: a mode governs only the calls no
|
|
5
|
-
* rule decided, so it can never reopen what a rule closed. The tests that
|
|
6
|
-
* matter are the ones that would catch a future change making
|
|
7
|
-
* `--permission-mode auto` able to run something the operator wrote `deny` for.
|
|
8
|
-
*/
|
|
9
|
-
export {};
|
|
10
|
-
//# sourceMappingURL=mode.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mode.test.d.ts","sourceRoot":"","sources":["../../../src/permissions/__tests__/mode.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|