@agentshouse/kit 0.1.0-alpha.3 → 0.1.0-alpha.31

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 (142) hide show
  1. package/README.md +722 -263
  2. package/bin/connect-linux.sh +200 -25
  3. package/bin/kit.js +179 -157
  4. package/bootstrap.json +17 -0
  5. package/package.json +7 -2
  6. package/src/adapter-mcp.js +76 -12
  7. package/src/agents.js +63 -8
  8. package/src/binding.js +52 -0
  9. package/src/blocks.js +2 -26
  10. package/src/bridge.js +28 -14
  11. package/src/bytes.js +19 -8
  12. package/src/configuration.js +13 -209
  13. package/src/connector-login.js +3 -84
  14. package/src/contract.js +36 -11
  15. package/src/delivery.js +4 -7
  16. package/src/directory.js +6 -26
  17. package/src/draft.js +4 -82
  18. package/src/git-main.js +138 -0
  19. package/src/git.js +62 -0
  20. package/src/google/calendar.js +39 -45
  21. package/src/google/drive.js +61 -186
  22. package/src/google/entries.js +346 -0
  23. package/src/google/gateway.js +3 -6
  24. package/src/google/gmail.js +33 -23
  25. package/src/google/oauth.js +106 -66
  26. package/src/google/source.js +21 -23
  27. package/src/host.js +6 -2
  28. package/src/house-main.js +65 -8
  29. package/src/house.js +446 -127
  30. package/src/how-we-work.md +25 -0
  31. package/src/inbound.js +2 -18
  32. package/src/kit-work-stream.js +118 -0
  33. package/src/launcher.js +46 -10
  34. package/src/local-files.js +3 -11
  35. package/src/login.js +23 -11
  36. package/src/mcp.js +18 -0
  37. package/src/mount.js +13 -21
  38. package/src/original.js +4 -4
  39. package/src/pacing.js +41 -0
  40. package/src/plan.js +37 -45
  41. package/src/repository.js +3 -61
  42. package/src/session-bin/git +2 -0
  43. package/src/setup.js +14 -15
  44. package/src/skill-set/ask-matt/PHASE-BOUNDARIES.md +55 -0
  45. package/src/skill-set/ask-matt/SKILL.md +91 -0
  46. package/src/skill-set/ask-matt/agents/openai.yaml +4 -0
  47. package/src/skill-set/code-review/LICENSE +21 -0
  48. package/src/skill-set/code-review/SKILL.md +89 -0
  49. package/src/skill-set/code-review/agents/openai.yaml +3 -0
  50. package/src/skill-set/codebase-design/DEEPENING.md +37 -0
  51. package/src/skill-set/codebase-design/DESIGN-IT-TWICE.md +44 -0
  52. package/src/skill-set/codebase-design/LICENSE +21 -0
  53. package/src/skill-set/codebase-design/SKILL.md +116 -0
  54. package/src/skill-set/codebase-design/agents/openai.yaml +3 -0
  55. package/src/skill-set/diagnosing-bugs/LICENSE +21 -0
  56. package/src/skill-set/diagnosing-bugs/SKILL.md +140 -0
  57. package/src/skill-set/diagnosing-bugs/agents/openai.yaml +3 -0
  58. package/src/skill-set/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
  59. package/src/skill-set/domain-modeling/ADR-FORMAT.md +47 -0
  60. package/src/skill-set/domain-modeling/CONTEXT-FORMAT.md +60 -0
  61. package/src/skill-set/domain-modeling/LICENSE +21 -0
  62. package/src/skill-set/domain-modeling/SKILL.md +76 -0
  63. package/src/skill-set/domain-modeling/agents/openai.yaml +3 -0
  64. package/src/skill-set/grill-me/LICENSE +21 -0
  65. package/src/skill-set/grill-me/SKILL.md +8 -0
  66. package/src/skill-set/grill-me/agents/openai.yaml +4 -0
  67. package/src/skill-set/grill-with-docs/LICENSE +21 -0
  68. package/src/skill-set/grill-with-docs/SKILL.md +8 -0
  69. package/src/skill-set/grill-with-docs/agents/openai.yaml +4 -0
  70. package/src/skill-set/grilling/LICENSE +21 -0
  71. package/src/{starter-set → skill-set}/grilling/SKILL.md +1 -1
  72. package/src/skill-set/handoff/LICENSE +21 -0
  73. package/src/skill-set/handoff/SKILL.md +17 -0
  74. package/src/skill-set/handoff/agents/openai.yaml +4 -0
  75. package/src/skill-set/implement/LICENSE +21 -0
  76. package/src/skill-set/implement/SKILL.md +16 -0
  77. package/src/skill-set/implement/agents/openai.yaml +4 -0
  78. package/src/skill-set/improve-codebase-architecture/HTML-REPORT.md +123 -0
  79. package/src/skill-set/improve-codebase-architecture/LICENSE +21 -0
  80. package/src/skill-set/improve-codebase-architecture/SKILL.md +72 -0
  81. package/src/skill-set/improve-codebase-architecture/agents/openai.yaml +4 -0
  82. package/src/skill-set/prototype/LICENSE +21 -0
  83. package/src/skill-set/prototype/LOGIC.md +67 -0
  84. package/src/skill-set/prototype/SKILL.md +28 -0
  85. package/src/skill-set/prototype/UI.md +112 -0
  86. package/src/skill-set/prototype/agents/openai.yaml +3 -0
  87. package/src/skill-set/research/LICENSE +21 -0
  88. package/src/skill-set/research/SKILL.md +14 -0
  89. package/src/skill-set/research/agents/openai.yaml +3 -0
  90. package/src/skill-set/resolving-merge-conflicts/LICENSE +21 -0
  91. package/src/skill-set/resolving-merge-conflicts/SKILL.md +16 -0
  92. package/src/skill-set/resolving-merge-conflicts/agents/openai.yaml +3 -0
  93. package/src/skill-set/tdd/LICENSE +21 -0
  94. package/src/skill-set/tdd/SKILL.md +40 -0
  95. package/src/skill-set/tdd/agents/openai.yaml +3 -0
  96. package/src/skill-set/tdd/mocking.md +59 -0
  97. package/src/skill-set/tdd/tests.md +77 -0
  98. package/src/skill-set/teach/GLOSSARY-FORMAT.md +35 -0
  99. package/src/skill-set/teach/LEARNING-RECORD-FORMAT.md +46 -0
  100. package/src/skill-set/teach/LICENSE +21 -0
  101. package/src/skill-set/teach/MISSION-FORMAT.md +31 -0
  102. package/src/skill-set/teach/RESOURCES-FORMAT.md +32 -0
  103. package/src/skill-set/teach/SKILL.md +141 -0
  104. package/src/skill-set/teach/agents/openai.yaml +4 -0
  105. package/src/skill-set/to-questionnaire/LICENSE +21 -0
  106. package/src/skill-set/to-questionnaire/SKILL.md +55 -0
  107. package/src/skill-set/to-questionnaire/agents/openai.yaml +4 -0
  108. package/src/skill-set/to-spec/LICENSE +21 -0
  109. package/src/skill-set/to-spec/SKILL.md +76 -0
  110. package/src/skill-set/to-spec/agents/openai.yaml +4 -0
  111. package/src/skill-set/to-tickets/LICENSE +21 -0
  112. package/src/skill-set/to-tickets/SKILL.md +106 -0
  113. package/src/skill-set/to-tickets/agents/openai.yaml +4 -0
  114. package/src/skill-set/wait-what/LICENSE +21 -0
  115. package/src/skill-set/wait-what/SKILL.md +8 -0
  116. package/src/skill-set/wait-what/agents/openai.yaml +4 -0
  117. package/src/skill-set/wayfinder/LICENSE +21 -0
  118. package/src/skill-set/wayfinder/SKILL.md +129 -0
  119. package/src/skill-set/wayfinder/agents/openai.yaml +4 -0
  120. package/src/skill-set/writing-for-agents/LICENSE +21 -0
  121. package/src/skill-set/writing-for-agents/SKILL-MECHANICS.md +22 -0
  122. package/src/skill-set/writing-for-agents/SKILL.md +83 -0
  123. package/src/skill-set/writing-for-agents/agents/openai.yaml +3 -0
  124. package/src/skill-set.js +85 -0
  125. package/src/source.js +93 -54
  126. package/src/state.js +19 -1
  127. package/src/sync-library.js +7 -11
  128. package/src/sync-state.js +16 -3
  129. package/src/sync.js +129 -41
  130. package/src/tasks.js +75 -0
  131. package/src/telegram-view.js +214 -0
  132. package/src/telegram.js +161 -66
  133. package/src/turn-frames.js +69 -0
  134. package/src/worker.js +685 -184
  135. package/src/working-copy.js +1221 -0
  136. package/src/workspace.js +40 -32
  137. package/src/google/declared.js +0 -146
  138. package/src/google/id.js +0 -1
  139. package/src/instance/google.js +0 -1
  140. package/src/starter-set.js +0 -17
  141. /package/src/{starter-set/grilling → skill-set/ask-matt}/LICENSE +0 -0
  142. /package/src/{starter-set → skill-set}/grilling/agents/openai.yaml +0 -0
package/src/workspace.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  releaseControl,
29
29
  reportWorkspaceOutcome,
30
30
  } from "./house.js";
31
- import { KitRefusal } from "./refusal.js";
31
+ import { houseFailed, KitRefusal } from "./refusal.js";
32
32
 
33
33
  const REQUIRED_CONTROLLERS = ["cpu", "memory"];
34
34
  const MEMINFO = "/proc/meminfo";
@@ -461,40 +461,48 @@ export async function serveWorkspaces(options, dependencies = {}) {
461
461
  const withdrawn = [];
462
462
  let reconciled = [];
463
463
  const passes = options.passes ?? Number.POSITIVE_INFINITY;
464
- for (let pass = 0; pass < passes; pass += 1) {
465
- const work = await maintainControl(
466
- session,
467
- async (signal) => {
468
- const acquired = await acquireWorkspaces(session, WORKSPACE_ACQUIRE_MAX, signal);
469
- reconciled = await reconcileWorkspaces(host, acquired.workspaces);
470
- for (const operation of acquired.operations) {
471
- let report;
472
- try {
473
- report = await performOperation(host, settings, operation);
474
- } catch (error) {
475
- if (!(error instanceof KitRefusal)) throw error;
476
- report = { outcome: "failed", refusal: error.message };
477
- }
478
- try {
479
- await reportWorkspaceOutcome(session, operation.operation, report, signal);
480
- } catch (error) {
481
- if (!(error instanceof KitRefusal) || error.code !== WORKSPACE_OPERATION_WITHDRAWN) {
482
- throw error;
464
+ try {
465
+ for (let pass = 0; pass < passes; pass += 1) {
466
+ const work = await maintainControl(
467
+ session,
468
+ async (signal) => {
469
+ const acquired = await acquireWorkspaces(session, WORKSPACE_ACQUIRE_MAX, signal);
470
+ reconciled = await reconcileWorkspaces(host, acquired.workspaces);
471
+ for (const operation of acquired.operations) {
472
+ let report;
473
+ try {
474
+ report = await performOperation(host, settings, operation);
475
+ } catch (error) {
476
+ if (!(error instanceof KitRefusal)) throw error;
477
+ report = { outcome: "failed", refusal: error.message };
483
478
  }
484
- withdrawn.push({ operation: operation.operation, kind: operation.kind });
485
- continue;
479
+ try {
480
+ await reportWorkspaceOutcome(session, operation.operation, report, signal);
481
+ } catch (error) {
482
+ if (!(error instanceof KitRefusal) || error.code !== WORKSPACE_OPERATION_WITHDRAWN) {
483
+ throw error;
484
+ }
485
+ withdrawn.push({ operation: operation.operation, kind: operation.kind });
486
+ continue;
487
+ }
488
+ settled.push({ operation: operation.operation, kind: operation.kind, ...report });
486
489
  }
487
- settled.push({ operation: operation.operation, kind: operation.kind, ...report });
488
- }
489
- return acquired;
490
- },
491
- options.signal,
492
- { release: false },
493
- );
494
- if (pass + 1 < passes && work.operations.length === 0) {
495
- await host.wait(WORKSPACE_POLL_MS);
490
+ return acquired;
491
+ },
492
+ options.signal,
493
+ { release: false },
494
+ ).catch((error) => {
495
+ if (!houseFailed(error)) throw error;
496
+ return null;
497
+ });
498
+ if (pass + 1 < passes && (work === null || work.operations.length === 0)) {
499
+ await host.wait(WORKSPACE_POLL_MS);
500
+ }
496
501
  }
502
+ } catch (error) {
503
+ if (!(error instanceof KitRefusal) || error.code !== "kit_command_cancelled") throw error;
504
+ } finally {
505
+ await releaseControl(session);
497
506
  }
498
- await releaseControl(session);
499
507
  return { settled, reconciled, withdrawn };
500
508
  }
@@ -1,146 +0,0 @@
1
- import { ITEM_BODY_MAX_BYTES } from "../contract.js";
2
- import { KitRefusal } from "../refusal.js";
3
- import { googleJson } from "./gateway.js";
4
-
5
- function valueAt(value, path) {
6
- let current = value;
7
- for (const segment of path.split(".")) {
8
- if (current === null || current === undefined || typeof current !== "object") return undefined;
9
- current = current[segment];
10
- }
11
- return current;
12
- }
13
-
14
- function requiredText(value, declaration) {
15
- if (typeof value !== "string" || value.length === 0) {
16
- throw new KitRefusal("google_provider_response_invalid", declaration);
17
- }
18
- return value;
19
- }
20
-
21
- function optionalText(value, declaration) {
22
- if (value === undefined || value === null) return null;
23
- return requiredText(value, declaration);
24
- }
25
-
26
- function cursorOf(value) {
27
- if (value === null) return { pageToken: null, checkpoint: null };
28
- let cursor;
29
- try {
30
- cursor = JSON.parse(value);
31
- } catch {
32
- throw new KitRefusal("google_checkpoint_invalid", "declared service");
33
- }
34
- if (
35
- typeof cursor !== "object" ||
36
- cursor === null ||
37
- (cursor.pageToken !== null && typeof cursor.pageToken !== "string") ||
38
- (cursor.checkpoint !== null && typeof cursor.checkpoint !== "string")
39
- ) {
40
- throw new KitRefusal("google_checkpoint_invalid", "declared service");
41
- }
42
- return cursor;
43
- }
44
-
45
- function composedBody(item, paths) {
46
- const parts = paths.map((path) => valueAt(item, path));
47
- if (parts.some((part) => !["string", "number", "boolean"].includes(typeof part))) {
48
- throw new KitRefusal("google_provider_response_invalid", "declared body");
49
- }
50
- const body = parts.map((part) => `${part}`).join("\n\n");
51
- if (Buffer.byteLength(body, "utf8") > ITEM_BODY_MAX_BYTES) {
52
- throw new KitRefusal("google_provider_response_invalid", "declared body");
53
- }
54
- return body;
55
- }
56
-
57
- function normalizedItem(service, item) {
58
- const fields = service.declaration.fields;
59
- const observedAt = requiredText(valueAt(item, fields.observedAt), "declared observed time");
60
- if (Number.isNaN(Date.parse(observedAt))) {
61
- throw new KitRefusal("google_provider_response_invalid", "declared observed time");
62
- }
63
- const container = requiredText(valueAt(item, fields.container), "declared container");
64
- const nativeVersion =
65
- fields.nativeVersion === null
66
- ? null
67
- : optionalText(valueAt(item, fields.nativeVersion), "declared native version");
68
- const providerModifiedAt =
69
- fields.providerModifiedAt === null
70
- ? null
71
- : optionalText(
72
- valueAt(item, fields.providerModifiedAt),
73
- "declared provider modification time",
74
- );
75
- if (providerModifiedAt !== null && Number.isNaN(Date.parse(providerModifiedAt))) {
76
- throw new KitRefusal("google_provider_response_invalid", "declared provider modification time");
77
- }
78
- return {
79
- namespace: `google/${service.service}`,
80
- nativeObjectId: requiredText(valueAt(item, fields.nativeId), "declared native id"),
81
- nativeVersion,
82
- providerModifiedAt:
83
- providerModifiedAt === null ? null : new Date(providerModifiedAt).toISOString(),
84
- observedAt: new Date(observedAt).toISOString(),
85
- body: composedBody(item, fields.body),
86
- author:
87
- fields.author === null
88
- ? null
89
- : optionalText(valueAt(item, fields.author), "declared author"),
90
- url:
91
- fields.url === null ? null : optionalText(valueAt(item, fields.url), "declared url"),
92
- attachments: [],
93
- container: `google/${service.service}/${container}`,
94
- };
95
- }
96
-
97
- export async function declaredPage(options, dependencies = {}) {
98
- const declared = options.service.declaration;
99
- const cursor = cursorOf(options.cursor);
100
- const url = new URL(declared.path, `https://${declared.host}`);
101
- for (const [name, value] of Object.entries(declared.query)) url.searchParams.set(name, value);
102
- url.searchParams.set(declared.pageSize, `${options.limit}`);
103
- if (cursor.pageToken !== null) {
104
- url.searchParams.set(declared.pageToken.request, cursor.pageToken);
105
- }
106
- if (cursor.checkpoint !== null) {
107
- url.searchParams.set(declared.pageToken.checkpointRequest, cursor.checkpoint);
108
- }
109
- const answer = await googleJson(
110
- {
111
- directory: options.directory,
112
- instance: options.instance,
113
- client: options.client,
114
- requiredScopes: declared.scopes,
115
- url: url.toString(),
116
- signal: options.signal,
117
- },
118
- dependencies,
119
- );
120
- const entries = valueAt(answer, declared.items);
121
- if (!Array.isArray(entries) || entries.length > options.limit) {
122
- throw new KitRefusal("google_provider_response_invalid", "declared items");
123
- }
124
- const pageToken = valueAt(answer, declared.pageToken.response);
125
- let next;
126
- if (pageToken !== undefined && pageToken !== null) {
127
- next = {
128
- pageToken: requiredText(pageToken, "declared page token"),
129
- checkpoint: cursor.checkpoint,
130
- };
131
- } else {
132
- next = {
133
- pageToken: null,
134
- checkpoint: requiredText(
135
- valueAt(answer, declared.pageToken.checkpointResponse),
136
- "declared checkpoint",
137
- ),
138
- };
139
- }
140
- return {
141
- items: entries.map((entry) => normalizedItem(options.service, entry)),
142
- dropped: [],
143
- cursor: JSON.stringify(next),
144
- more: pageToken !== undefined && pageToken !== null,
145
- };
146
- }
package/src/google/id.js DELETED
@@ -1 +0,0 @@
1
- export const GOOGLE_DRIVE_ID = /^[A-Za-z0-9_-]{1,512}$/;
@@ -1 +0,0 @@
1
- export const GOOGLE_OAUTH_CLIENT = Object.freeze({"id":"911965338518-867gdvuddb7kdkjo3qvpv6gds369alb7.apps.googleusercontent.com","secret":"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"});
@@ -1,17 +0,0 @@
1
- import { cp, mkdir, symlink, writeFile } from "node:fs/promises";
2
- import { join } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
-
5
- const AGENTS_INSTRUCTION = "The agents.house `house` CLI is available: run `house --help`.\n";
6
- const GRILLING_SOURCE = fileURLToPath(new URL("starter-set/grilling/", import.meta.url));
7
-
8
- export async function seedStarterSet(target) {
9
- await mkdir(target, { recursive: true });
10
- await writeFile(join(target, "AGENTS.md"), AGENTS_INSTRUCTION);
11
- await symlink("AGENTS.md", join(target, "CLAUDE.md"));
12
- const skills = join(target, ".agents", "skills");
13
- await mkdir(skills, { recursive: true });
14
- await cp(GRILLING_SOURCE, join(skills, "grilling"), { recursive: true });
15
- await mkdir(join(target, ".claude"), { recursive: true });
16
- await symlink(join("..", ".agents", "skills"), join(target, ".claude", "skills"));
17
- }